mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-07-14 19:43:44 +00:00
refactor(#89): Address PR comments
This commit is contained in:
@@ -26,6 +26,9 @@ export const PUT = async (event: RequestEvent) => {
|
|||||||
const patch: Record<string, unknown> = {};
|
const patch: Record<string, unknown> = {};
|
||||||
if (body.folderId !== undefined) patch.folderId = body.folderId;
|
if (body.folderId !== undefined) patch.folderId = body.folderId;
|
||||||
if (body.path !== undefined) patch.path = body.path;
|
if (body.path !== undefined) patch.path = body.path;
|
||||||
|
if (Object.keys(patch).length === 0) {
|
||||||
|
return json({ error: 'No fields to update' }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
const { data, error } = await event.locals.supabase
|
const { data, error } = await event.locals.supabase
|
||||||
.from('pokedex_export_integrations')
|
.from('pokedex_export_integrations')
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ export const GET = async (event: RequestEvent) => {
|
|||||||
const env = getEnv();
|
const env = getEnv();
|
||||||
const clientId = env.DROPBOX_OAUTH_CLIENT_ID;
|
const clientId = env.DROPBOX_OAUTH_CLIENT_ID;
|
||||||
if (!clientId) {
|
if (!clientId) {
|
||||||
throw redirect(302, `/pokedex/${pokedexId}?export=dropbox-missing-client`);
|
const missingClientRedirect = pokedexId
|
||||||
|
? `/pokedex/${pokedexId}?export=dropbox-missing-client`
|
||||||
|
: '/pokedex?export=dropbox-missing-client';
|
||||||
|
throw redirect(302, missingClientRedirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = createOAuthState();
|
const state = createOAuthState();
|
||||||
|
|||||||
@@ -89,16 +89,21 @@ export const GET = async (event: RequestEvent) => {
|
|||||||
const fileName = oauthState.fileName?.trim() ? oauthState.fileName : null;
|
const fileName = oauthState.fileName?.trim() ? oauthState.fileName : null;
|
||||||
const folderId = oauthState.folderId?.trim() ? oauthState.folderId : null;
|
const folderId = oauthState.folderId?.trim() ? oauthState.folderId : null;
|
||||||
|
|
||||||
await repo.upsert({
|
try {
|
||||||
provider: 'google_drive',
|
await repo.upsert({
|
||||||
enabled: true,
|
provider: 'google_drive',
|
||||||
fileName,
|
enabled: true,
|
||||||
folderId,
|
fileName,
|
||||||
accessToken: tokenData.access_token,
|
folderId,
|
||||||
refreshToken: tokenData.refresh_token ?? null,
|
accessToken: tokenData.access_token,
|
||||||
accessTokenExpiresAt: expiresAt,
|
refreshToken: tokenData.refresh_token ?? null,
|
||||||
metadata: tokenData.scope ? { scope: tokenData.scope } : null
|
accessTokenExpiresAt: expiresAt,
|
||||||
});
|
metadata: tokenData.scope ? { scope: tokenData.scope } : null
|
||||||
|
});
|
||||||
|
} catch (saveError) {
|
||||||
|
console.error('Google Drive integration save failed:', saveError);
|
||||||
|
throw redirect(302, `${returnTo}-error`);
|
||||||
|
}
|
||||||
|
|
||||||
throw redirect(302, `${returnTo}-connected`);
|
throw redirect(302, `${returnTo}-connected`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ export const GET = async (event: RequestEvent) => {
|
|||||||
const env = getEnv();
|
const env = getEnv();
|
||||||
const clientId = env.GOOGLE_OAUTH_CLIENT_ID;
|
const clientId = env.GOOGLE_OAUTH_CLIENT_ID;
|
||||||
if (!clientId) {
|
if (!clientId) {
|
||||||
throw redirect(302, `/pokedex/${pokedexId}?export=google-missing-client`);
|
const missingClientRedirect = pokedexId
|
||||||
|
? `/pokedex/${pokedexId}?export=google-missing-client`
|
||||||
|
: '/pokedex?export=google-missing-client';
|
||||||
|
throw redirect(302, missingClientRedirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = createOAuthState();
|
const state = createOAuthState();
|
||||||
|
|||||||
@@ -121,6 +121,7 @@
|
|||||||
<a
|
<a
|
||||||
href={getGoogleFolderUrl(googleIntegration.folderId)}
|
href={getGoogleFolderUrl(googleIntegration.folderId)}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
class="link link-primary"
|
class="link link-primary"
|
||||||
>
|
>
|
||||||
Open Drive folder
|
Open Drive folder
|
||||||
@@ -156,6 +157,7 @@
|
|||||||
<a
|
<a
|
||||||
href={getDropboxFolderUrl(dropboxIntegration.path)}
|
href={getDropboxFolderUrl(dropboxIntegration.path)}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
class="link link-primary"
|
class="link link-primary"
|
||||||
>
|
>
|
||||||
Open Dropbox folder
|
Open Dropbox folder
|
||||||
|
|||||||
@@ -64,6 +64,21 @@
|
|||||||
let exportInFlightGeneration = 0;
|
let exportInFlightGeneration = 0;
|
||||||
let toggleFlushTimer: ReturnType<typeof setTimeout> | null = null;
|
let toggleFlushTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
|
function resetExportState() {
|
||||||
|
if (exportTimer) {
|
||||||
|
clearTimeout(exportTimer);
|
||||||
|
exportTimer = null;
|
||||||
|
}
|
||||||
|
if (toggleFlushTimer) {
|
||||||
|
clearTimeout(toggleFlushTimer);
|
||||||
|
toggleFlushTimer = null;
|
||||||
|
}
|
||||||
|
exportAfterFlush = false;
|
||||||
|
exportInFlight = false;
|
||||||
|
exportGeneration = 0;
|
||||||
|
exportInFlightGeneration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
function scheduleExportIfIdle() {
|
function scheduleExportIfIdle() {
|
||||||
if (!browser) return;
|
if (!browser) return;
|
||||||
if (!pokedexId) return;
|
if (!pokedexId) return;
|
||||||
@@ -77,10 +92,15 @@
|
|||||||
exportInFlight = true;
|
exportInFlight = true;
|
||||||
exportInFlightGeneration = exportGeneration;
|
exportInFlightGeneration = exportGeneration;
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/pokedexes/${pokedexId}/export`, {
|
const response = await fetch(`/api/pokedexes/${pokedexId}/export`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'include'
|
credentials: 'include'
|
||||||
});
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
const body = await response.text().catch(() => '');
|
||||||
|
console.error('Auto-export failed:', response.status, body);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (exportGeneration === exportInFlightGeneration) {
|
if (exportGeneration === exportInFlightGeneration) {
|
||||||
exportAfterFlush = false;
|
exportAfterFlush = false;
|
||||||
}
|
}
|
||||||
@@ -121,6 +141,9 @@
|
|||||||
catchWriteQueueUnsubscribe?.();
|
catchWriteQueueUnsubscribe?.();
|
||||||
catchWriteQueueUnsubscribe = null;
|
catchWriteQueueUnsubscribe = null;
|
||||||
});
|
});
|
||||||
|
onDestroy(() => {
|
||||||
|
resetExportState();
|
||||||
|
});
|
||||||
|
|
||||||
function openPokemonModal(pokemon: CombinedData) {
|
function openPokemonModal(pokemon: CombinedData) {
|
||||||
selectedPokemon = pokemon;
|
selectedPokemon = pokemon;
|
||||||
@@ -139,6 +162,8 @@
|
|||||||
const desiredKey = `${localUser.id}:${pokedexId}`;
|
const desiredKey = `${localUser.id}:${pokedexId}`;
|
||||||
if (catchWriteQueue && catchWriteQueueKey === desiredKey) return;
|
if (catchWriteQueue && catchWriteQueueKey === desiredKey) return;
|
||||||
|
|
||||||
|
resetExportState();
|
||||||
|
|
||||||
// Unsubscribe from the previous queue's status store before replacing the queue.
|
// Unsubscribe from the previous queue's status store before replacing the queue.
|
||||||
catchWriteQueueUnsubscribe?.();
|
catchWriteQueueUnsubscribe?.();
|
||||||
catchWriteQueueUnsubscribe = null;
|
catchWriteQueueUnsubscribe = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user