diff --git a/frontend/src/components/subscriptions/SourceCard.vue b/frontend/src/components/subscriptions/SourceCard.vue index 03464f8..7b8f9bc 100644 --- a/frontend/src/components/subscriptions/SourceCard.vue +++ b/frontend/src/components/subscriptions/SourceCard.vue @@ -25,9 +25,17 @@ size="x-small" color="error" variant="tonal" label >{{ source.consecutive_failures }} err backfill ({{ source.backfill_runs_remaining }}×) + >Backfilling{{ source.backfill_chunks ? ` (${source.backfill_chunks})` : '' }} + Backfilled + Stalled
@@ -40,11 +48,13 @@ - mdi-magnify-scan - Deep scan + {{ source.backfill_state === 'running' ? 'mdi-stop' : 'mdi-magnify-scan' }} + + {{ source.backfill_state === 'running' ? 'Stop backfill' : 'Backfill full history' }} + mdi-pencil diff --git a/frontend/src/components/subscriptions/SourceRow.vue b/frontend/src/components/subscriptions/SourceRow.vue index 011645f..9fe412e 100644 --- a/frontend/src/components/subscriptions/SourceRow.vue +++ b/frontend/src/components/subscriptions/SourceRow.vue @@ -32,11 +32,17 @@ size="x-small" color="error" variant="tonal" label >{{ source.consecutive_failures }} - backfill ({{ source.backfill_runs_remaining }}×) - + >Backfilling{{ source.backfill_chunks ? ` (${source.backfill_chunks})` : '' }} + Backfilled + Stalled 0 @@ -49,13 +55,15 @@ Check now - mdi-magnify-scan + {{ source.backfill_state === 'running' ? 'mdi-stop' : 'mdi-magnify-scan' }} - Deep scan — walk full history for next few runs + {{ source.backfill_state === 'running' + ? 'Stop backfill' + : 'Backfill — walk the full post history until complete' }} 10) { - toast({ text: 'Deep scan: runs must be 1–10', type: 'error' }) - return - } + const running = source.backfill_state === 'running' try { - await store.setBackfill(source.id, runs, source.artist_id) - toast({ - text: `Deep scan armed for ${runs} run${runs === 1 ? '' : 's'}`, - type: 'success', - }) + if (running) { + await store.stopBackfill(source.id, source.artist_id) + toast({ text: `Backfill stopped for ${source.artist_name}`, type: 'success' }) + } else { + await store.startBackfill(source.id, source.artist_id) + toast({ text: `Backfill started for ${source.artist_name}`, type: 'success' }) + } await store.loadAll() } catch (e) { toast({ - text: `Deep scan failed: ${e?.detail || e?.message || e}`, + text: `Backfill ${running ? 'stop' : 'start'} failed: ${e?.detail || e?.message || e}`, type: 'error', }) } diff --git a/frontend/src/stores/sources.js b/frontend/src/stores/sources.js index 2e9406e..5eb90fe 100644 --- a/frontend/src/stores/sources.js +++ b/frontend/src/stores/sources.js @@ -85,11 +85,16 @@ export const useSourcesStore = defineStore('sources', () => { } } - // Plan #544: arm a source for backfill mode. The next `runs` download - // runs (default 3) walk gallery-dl's full post history instead of - // exiting early at the first contiguous archived block. - async function setBackfill(id, runs = 3, artistIdHint = null) { - const body = await api.post(`/api/sources/${id}/backfill`, { body: { runs } }) + // Plan #693: start/stop a run-until-done backfill. 'start' walks the full + // post history in time-boxed chunks until it reaches the bottom (then the + // source shows backfill_state 'complete'); 'stop' cancels back to tick mode. + async function startBackfill(id, artistIdHint = null) { + const body = await api.post(`/api/sources/${id}/backfill`, { body: { action: 'start' } }) + _invalidate(artistIdHint ?? body.artist_id) + return body + } + async function stopBackfill(id, artistIdHint = null) { + const body = await api.post(`/api/sources/${id}/backfill`, { body: { action: 'stop' } }) _invalidate(artistIdHint ?? body.artist_id) return body } @@ -120,7 +125,8 @@ export const useSourcesStore = defineStore('sources', () => { loadAll, loadForArtist, create, update, remove, checkNow, - setBackfill, + startBackfill, + stopBackfill, findOrCreateArtist, autocompleteArtist, loadScheduleStatus, sourcesByArtistGrouped,