fix(progress): currentPhase and live messages now update in real-time
Some checks failed
Build & Push Docker Image / test-and-build (push) Failing after 35s
Some checks failed
Build & Push Docker Image / test-and-build (push) Failing after 35s
Three issues causing the 'prepping → done' jump: 1. +page.svelte updateQueueItem: never applied update.phase to currentPhase, so CookingHero always showed 'Prepping' regardless of actual backend state. Fixed: currentPhase: update.phase ?? prev. 2. +page.svelte updateQueueItem: progress events (type:'progress') were discarded. Fixed: append data.event to progressEvents array so live messages are available to components. 3. stream/+server.ts: initial SSE snapshot omitted phase field, so items already in-progress on page load showed wrong phase. Fixed. Bonus: CookingHero now shows the latest user-friendly progress message (status/complete/model_loading types) as a live scrolling sub-line under the phase hint. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -184,12 +184,21 @@
|
||||
function updateQueueItem(update: QueueStatusUpdate) {
|
||||
const idx = items.findIndex((i) => i.id === update.itemId);
|
||||
if (idx >= 0) {
|
||||
const prev = items[idx];
|
||||
// Append progress events (type: 'progress' carries data.event)
|
||||
const newEvents = update.data?.event
|
||||
? [...(prev.progressEvents ?? []), update.data.event]
|
||||
: (prev.progressEvents ?? []);
|
||||
|
||||
items[idx] = {
|
||||
...items[idx],
|
||||
...prev,
|
||||
status: update.status,
|
||||
phases: update.progress || items[idx].phases,
|
||||
results: update.results || items[idx].results,
|
||||
error: update.error || items[idx].error,
|
||||
// currentPhase is sent as update.phase on status_change events
|
||||
currentPhase: update.phase ?? prev.currentPhase,
|
||||
phases: update.progress || prev.phases,
|
||||
progressEvents: newEvents,
|
||||
results: update.results || prev.results,
|
||||
error: update.error || prev.error,
|
||||
updatedAt: update.timestamp
|
||||
};
|
||||
// Keep selectedItem in sync
|
||||
|
||||
@@ -124,6 +124,7 @@ export const GET: RequestHandler = async ({ url, request }) => {
|
||||
status: item.status,
|
||||
timestamp: new Date().toISOString(),
|
||||
url: item.url,
|
||||
phase: item.currentPhase,
|
||||
progress: item.phases,
|
||||
results: item.results,
|
||||
error: item.error
|
||||
|
||||
@@ -40,6 +40,19 @@
|
||||
if (diff < 3600) return Math.floor(diff / 60) + 'm ago';
|
||||
return Math.floor(diff / 3600) + 'h ago';
|
||||
}
|
||||
|
||||
// Latest progress message — shown as a live sub-status inside the hero.
|
||||
// Only show user-friendly event types (skip low-level extraction method attempts).
|
||||
const SHOW_TYPES = new Set(['status', 'complete', 'model_loading', 'error', 'retry']);
|
||||
const latestMsg = $derived.by(() => {
|
||||
const events = item.progressEvents ?? [];
|
||||
for (let i = events.length - 1; i >= 0; i--) {
|
||||
const ev = events[i];
|
||||
if (!ev?.message || ev.message.length <= 3) continue;
|
||||
if (SHOW_TYPES.has(ev.type)) return ev.message as string;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<button class="ic-btn-reset hero-card" onclick={onTap}>
|
||||
@@ -58,6 +71,9 @@
|
||||
<div class="text-area">
|
||||
<div class="phase-label">{phaseMap[item.currentPhase ?? 'extraction']}…</div>
|
||||
<div class="phase-hint">{phaseHints[item.currentPhase ?? 'extraction']}</div>
|
||||
{#if latestMsg}
|
||||
<div class="live-msg ic-pulse">{latestMsg}</div>
|
||||
{/if}
|
||||
<span class="source-chip">{username(item.url)}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -147,7 +163,17 @@
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
line-height: 1.35;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.live-msg {
|
||||
font-size: 11px;
|
||||
font-family: var(--font-mono);
|
||||
color: var(--pink);
|
||||
line-height: 1.35;
|
||||
margin-bottom: 6px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.source-chip {
|
||||
display: inline-block;
|
||||
|
||||
Reference in New Issue
Block a user