diff --git a/internal/web/videocard_internal_test.go b/internal/web/videocard_internal_test.go index 4bf2968..305065a 100644 --- a/internal/web/videocard_internal_test.go +++ b/internal/web/videocard_internal_test.go @@ -46,7 +46,7 @@ func TestVideoCard_State1_Summarized(t *testing.T) { t.Errorf("state 1: expected AI provider chip, got:\n%s", html) } noActionButton(t, html, "summarized") - if strings.Contains(html, "Summarize now") { + if strings.Contains(html, "Summarize") { t.Errorf("state 1: no nudge button on a summarized card, got:\n%s", html) } } @@ -64,7 +64,7 @@ func TestVideoCard_State2_NoTranscript(t *testing.T) { t.Errorf("state 2: expected 'No transcript available' text, got:\n%s", html) } noActionButton(t, html, "none-transcript") - if strings.Contains(html, "Summarize now") { + if strings.Contains(html, "Summarize") { t.Errorf("state 2: no nudge button when there are no captions, got:\n%s", html) } } @@ -84,7 +84,7 @@ func TestVideoCard_State3_Queued(t *testing.T) { noActionButton(t, html, "queued") } -// TestVideoCard_State4_RateLimited — quiet status + "Summarize now" → retry-now URL. +// TestVideoCard_State4_RateLimited — quiet status + "Summarize" → retry-now URL. func TestVideoCard_State4_RateLimited(t *testing.T) { html := renderVideoCard(t, store.SummaryRow{ VideoID: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", @@ -93,11 +93,11 @@ func TestVideoCard_State4_RateLimited(t *testing.T) { TranscriptStatus: "rate_limited", }) - if !strings.Contains(html, "Fetching soon") { - t.Errorf("state 4: expected 'Fetching soon' status text, got:\n%s", html) + if !strings.Contains(html, "In queue") { + t.Errorf("state 4: expected 'In queue' status text, got:\n%s", html) } - if !strings.Contains(html, "Summarize now") { - t.Errorf("state 4: expected 'Summarize now' button, got:\n%s", html) + if !strings.Contains(html, "Summarize") { + t.Errorf("state 4: expected 'Summarize' button, got:\n%s", html) } if !strings.Contains(html, "retry-now") { t.Errorf("state 4: expected retry-now URL in form action, got:\n%s", html) @@ -110,7 +110,7 @@ func TestVideoCard_State4_RateLimited(t *testing.T) { } } -// TestVideoCard_State5_Pending — quiet status + "Summarize now" → summarize URL. +// TestVideoCard_State5_Pending — quiet status + "Summarize" → summarize URL. func TestVideoCard_State5_Pending(t *testing.T) { html := renderVideoCard(t, store.SummaryRow{ VideoID: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", @@ -121,8 +121,8 @@ func TestVideoCard_State5_Pending(t *testing.T) { if !strings.Contains(html, "Not summarized") { t.Errorf("state 5: expected 'Not summarized' status text, got:\n%s", html) } - if !strings.Contains(html, "Summarize now") { - t.Errorf("state 5: expected 'Summarize now' button, got:\n%s", html) + if !strings.Contains(html, "Summarize") { + t.Errorf("state 5: expected 'Summarize' button, got:\n%s", html) } if !strings.Contains(html, "/summarize") { t.Errorf("state 5: expected summarize URL in form action, got:\n%s", html) diff --git a/internal/web/view.go b/internal/web/view.go index 46b4bd9..79103bc 100644 --- a/internal/web/view.go +++ b/internal/web/view.go @@ -538,6 +538,7 @@ a.btn, a.btn:visited { color: var(--accent-fg); } .pipeline-bar { display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap; margin-bottom: var(--s3); font-size: .8rem; color: var(--muted); } .pipeline-bar span { display: flex; align-items: center; gap: var(--s1); } .pipeline-bar span + span::before { content: "·"; margin-right: var(--s1); } +.pipeline-note { margin: calc(-1 * var(--s2)) 0 var(--s3); font-size: .8rem; line-height: 1.5; max-width: 40rem; } .card-nudge-form { display: inline; } .btn-quiet { font: inherit; font-size: .72rem; font-weight: 600; padding: .15rem .55rem; border-radius: 999px; border: 1px solid var(--accent); background: transparent; color: var(--accent); cursor: pointer; } .btn-quiet:hover { background: var(--accent-weak); } diff --git a/internal/web/views.templ b/internal/web/views.templ index c3b3ec9..e55b3df 100644 --- a/internal/web/views.templ +++ b/internal/web/views.templ @@ -111,22 +111,29 @@ templ ListPage(rows []store.SummaryRow, f Filter, stats PipelineStats, flash str if stats.RateLimited > 0 || stats.Pending > 0 || stats.NoText > 0 { @pipelineBar(stats) } + if stats.RateLimited+stats.Pending > 0 { +

+ Tapir fetches captions slowly on purpose, to respect YouTube's limits — + new summaries land gradually. Check back tomorrow. +

+ }
@summaryList(rows, hasConnected)
} } +// pipelineBar is the one-line backlog status. Counts are framed by what the user +// can read NOW ("ready"), what is waiting behind the honest caption rate limit +// ("in queue" = pending + rate-limited, never "fetching soon" — see A3/ADR-014), +// and what is permanently unreadable ("no captions"). templ pipelineBar(s PipelineStats) {
if s.Summarized > 0 { - { fmt.Sprintf("%d summarized", s.Summarized) } + { fmt.Sprintf("%d ready", s.Summarized) } } - if s.RateLimited > 0 { - { fmt.Sprintf("%d fetching soon", s.RateLimited) } - } - if s.Pending > 0 { - { fmt.Sprintf("%d pending", s.Pending) } + if s.RateLimited+s.Pending > 0 { + { fmt.Sprintf("%d in queue", s.RateLimited+s.Pending) } } if s.NoText > 0 { { fmt.Sprintf("%d no captions", s.NoText) } @@ -163,8 +170,8 @@ templ summaryList(rows []store.SummaryRow, hasConnected bool) { if len(rows) == 0 { if hasConnected {
- Your YouTube account is connected! - Run tapir run to discover your subscriptions. Videos will appear here once discovered. In manual mode, each new video gets a Summarize button. + Your account is connected + Tapir is finding your subscriptions and fetching captions — summaries appear here gradually. Check back later.
} else {
@@ -186,10 +193,10 @@ templ summaryList(rows []store.SummaryRow, hasConnected bool) { // /v/{id}/retry-now (HTMX swaps outerHTML). Five footer states, status-primary: // 1. Summarized — preview + chip + actions; no button. // 2. No captions (TranscriptStatus=="none") — terminal; "No transcript available"; no button. -// 3. Queued (SummarizeRequested) — "Queued · waiting for the next run"; no button. -// 4. Rate-limited — "Fetching soon" + quiet "Summarize now" → /retry-now. -// 5. Pending (else) — "Not summarized" + quiet "Summarize now" → /summarize. -// States 4 and 5 use one verb ("Summarize now") and one style (.btn-quiet); the +// 3. Queued (SummarizeRequested) — "Queued · summarizing shortly"; no button. +// 4. Rate-limited — "In queue" + quiet "Summarize" → /retry-now. +// 5. Pending (else) — "Not summarized" + quiet "Summarize" → /summarize. +// States 4 and 5 use one verb ("Summarize") and one style (.btn-quiet); the // backend side-effect difference (clear-backoff vs. set-flag) is invisible to users. templ VideoCard(r store.SummaryRow) {
  • @@ -222,12 +229,13 @@ templ VideoCard(r store.SummaryRow) { // State 2: no captions — terminal dead-end; nothing the user can do. No transcript available } else if r.SummarizeRequested { - // State 3: queued for the next scheduled pass. + // State 3: queued — being summarized on the next pass; no scheduler jargon. Queued - waiting for the next run + summarizing shortly } else if r.TranscriptStatus == "rate_limited" { - // State 4: rate-limited — quiet status + quiet nudge button → retry-now handler. - Fetching soon… + // State 4: rate-limited — honest "in queue" status (NOT "fetching soon", + // which oversells imminence) + a quiet nudge → retry-now handler. + In queue
    - +
    } else { // State 5: pending — discovered, not yet attempted; nudge button → summarize handler. @@ -249,7 +257,7 @@ templ VideoCard(r store.SummaryRow) { hx-swap="outerHTML" class="card-nudge-form" > - + }
  • diff --git a/internal/web/views_templ.go b/internal/web/views_templ.go index d27e9ba..c5d93ad 100644 --- a/internal/web/views_templ.go +++ b/internal/web/views_templ.go @@ -359,7 +359,17 @@ func ListPage(rows []store.SummaryRow, f Filter, stats PipelineStats, flash stri return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if stats.RateLimited+stats.Pending > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "

    Tapir fetches captions slowly on purpose, to respect YouTube's limits — new summaries land gradually. Check back tomorrow.

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -367,7 +377,7 @@ func ListPage(rows []store.SummaryRow, f Filter, stats PipelineStats, flash stri if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -381,6 +391,10 @@ func ListPage(rows []store.SummaryRow, f Filter, stats PipelineStats, flash stri }) } +// pipelineBar is the one-line backlog status. Counts are framed by what the user +// can read NOW ("ready"), what is waiting behind the honest caption rate limit +// ("in queue" = pending + rate-limited, never "fetching soon" — see A3/ADR-014), +// and what is permanently unreadable ("no captions"). func pipelineBar(s PipelineStats) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -402,40 +416,21 @@ func pipelineBar(s PipelineStats) templ.Component { templ_7745c5c3_Var14 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if s.Summarized > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d summarized", s.Summarized)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 123, Col: 53} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if s.RateLimited > 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d fetching soon", s.RateLimited)) + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d ready", s.Summarized)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 126, Col: 57} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 133, Col: 48} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -444,17 +439,17 @@ func pipelineBar(s PipelineStats) templ.Component { return templ_7745c5c3_Err } } - if s.Pending > 0 { + if s.RateLimited+s.Pending > 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d pending", s.Pending)) + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d in queue", s.RateLimited+s.Pending)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 129, Col: 47} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 136, Col: 62} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -468,12 +463,12 @@ func pipelineBar(s PipelineStats) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var18 string - templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d no captions", s.NoText)) + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d no captions", s.NoText)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 132, Col: 64} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 139, Col: 64} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -506,21 +501,21 @@ func filterForm(f Filter) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var19 := templ.GetChildren(ctx) - if templ_7745c5c3_Var19 == nil { - templ_7745c5c3_Var19 = templ.NopComponent + templ_7745c5c3_Var18 := templ.GetChildren(ctx) + if templ_7745c5c3_Var18 == nil { + templ_7745c5c3_Var18 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
    Your account is connected Tapir is finding your subscriptions and fetching captions — summaries appear here gradually. Check back later.
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -650,13 +645,13 @@ func VideoCard(r store.SummaryRow) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var24 := templ.GetChildren(ctx) - if templ_7745c5c3_Var24 == nil { - templ_7745c5c3_Var24 = templ.NopComponent + templ_7745c5c3_Var23 := templ.GetChildren(ctx) + if templ_7745c5c3_Var23 == nil { + templ_7745c5c3_Var23 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - var templ_7745c5c3_Var25 = []any{"card", templ.KV("card-pending", !r.Summarized)} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var25...) + var templ_7745c5c3_Var24 = []any{"card", templ.KV("card-pending", !r.Summarized)} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var24...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -664,12 +659,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var26 string - templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var25).String()) + var templ_7745c5c3_Var25 string + templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var24).String()) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 1, Col: 0} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var26) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var25) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -677,12 +672,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var27 string - templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.ResolveAttributeValue("video-" + r.VideoID) + var templ_7745c5c3_Var26 string + templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.ResolveAttributeValue("video-" + r.VideoID) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 195, Col: 88} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 202, Col: 88} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var27) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var26) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -695,12 +690,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var28 templ.SafeURL - templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinURLErrs(videoURL(r.VideoID)) + var templ_7745c5c3_Var27 templ.SafeURL + templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(videoURL(r.VideoID)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 197, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 204, Col: 56} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -708,12 +703,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var29 string - templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(displayTitle(r)) + var templ_7745c5c3_Var28 string + templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(displayTitle(r)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 197, Col: 76} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 204, Col: 76} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -726,12 +721,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var30 string - templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(displayTitle(r)) + var templ_7745c5c3_Var29 string + templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(displayTitle(r)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 199, Col: 44} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 206, Col: 44} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -745,12 +740,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var31 string - templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(cardMeta(r)) + var templ_7745c5c3_Var30 string + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(cardMeta(r)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 202, Col: 39} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 209, Col: 39} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -765,12 +760,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var32 string - templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(p) + var templ_7745c5c3_Var31 string + templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(p) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 206, Col: 33} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 213, Col: 33} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -794,12 +789,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var33 string - templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(r.AIProvider) + var templ_7745c5c3_Var32 string + templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(r.AIProvider) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 213, Col: 38} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 220, Col: 38} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -827,12 +822,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var34 string - templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(r.Actions, ", ")) + var templ_7745c5c3_Var33 string + templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(r.Actions, ", ")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 219, Col: 61} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 226, Col: 61} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -847,21 +842,21 @@ func VideoCard(r store.SummaryRow) templ.Component { return templ_7745c5c3_Err } } else if r.SummarizeRequested { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, " Queued waiting for the next run") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, " Queued summarizing shortly") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else if r.TranscriptStatus == "rate_limited" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, " Fetching soon…In queue") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "\" hx-swap=\"outerHTML\" class=\"card-nudge-form\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -900,12 +895,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var38 templ.SafeURL - templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinURLErrs(summarizeURL(r.VideoID)) + var templ_7745c5c3_Var37 templ.SafeURL + templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinURLErrs(summarizeURL(r.VideoID)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 246, Col: 37} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 254, Col: 37} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -913,12 +908,12 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var39 string - templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(string(summarizeURL(r.VideoID))) + var templ_7745c5c3_Var38 string + templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.ResolveAttributeValue(string(summarizeURL(r.VideoID))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 247, Col: 46} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 255, Col: 46} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var38) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -926,16 +921,16 @@ func VideoCard(r store.SummaryRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var40 string - templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue("#video-" + r.VideoID) + var templ_7745c5c3_Var39 string + templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue("#video-" + r.VideoID) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 248, Col: 38} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 256, Col: 38} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" hx-swap=\"outerHTML\" class=\"card-nudge-form\">") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" hx-swap=\"outerHTML\" class=\"card-nudge-form\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -969,9 +964,9 @@ func TapirSpinner() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var41 := templ.GetChildren(ctx) - if templ_7745c5c3_Var41 == nil { - templ_7745c5c3_Var41 = templ.NopComponent + templ_7745c5c3_Var40 := templ.GetChildren(ctx) + if templ_7745c5c3_Var40 == nil { + templ_7745c5c3_Var40 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "
    ")
    @@ -1002,12 +997,12 @@ func TapirSpinner() templ.Component {
     		if templ_7745c5c3_Err != nil {
     			return templ_7745c5c3_Err
     		}
    -		var templ_7745c5c3_Var42 string
    -		templ_7745c5c3_Var42, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues("color:" + CharmMint)
    +		var templ_7745c5c3_Var41 string
    +		templ_7745c5c3_Var41, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues("color:" + CharmMint)
     		if templ_7745c5c3_Err != nil {
    -			return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 269, Col: 82}
    +			return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 277, Col: 82}
     		}
    -		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
    +		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
     		if templ_7745c5c3_Err != nil {
     			return templ_7745c5c3_Err
     		}
    @@ -1015,12 +1010,12 @@ func TapirSpinner() templ.Component {
     		if templ_7745c5c3_Err != nil {
     			return templ_7745c5c3_Err
     		}
    -		var templ_7745c5c3_Var43 string
    -		templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(tapirBarFill)
    +		var templ_7745c5c3_Var42 string
    +		templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(tapirBarFill)
     		if templ_7745c5c3_Err != nil {
    -			return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 269, Col: 99}
    +			return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 277, Col: 99}
     		}
    -		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
    +		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
     		if templ_7745c5c3_Err != nil {
     			return templ_7745c5c3_Err
     		}
    @@ -1053,21 +1048,21 @@ func processingCard(r store.SummaryRow) templ.Component {
     			}()
     		}
     		ctx = templ.InitializeContext(ctx)
    -		templ_7745c5c3_Var44 := templ.GetChildren(ctx)
    -		if templ_7745c5c3_Var44 == nil {
    -			templ_7745c5c3_Var44 = templ.NopComponent
    +		templ_7745c5c3_Var43 := templ.GetChildren(ctx)
    +		if templ_7745c5c3_Var43 == nil {
    +			templ_7745c5c3_Var43 = templ.NopComponent
     		}
     		ctx = templ.ClearChildren(ctx)
     		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "
  • Current mode: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var76 string - templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(summarizeModeLabel(auto)) + var templ_7745c5c3_Var75 string + templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.JoinStringErrs(summarizeModeLabel(auto)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 479, Col: 53} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 487, Col: 53} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var75)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1759,12 +1754,12 @@ func summarizeModeControl(auto bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var77 string - templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolStr(!auto)) + var templ_7745c5c3_Var76 string + templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolStr(!auto)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 487, Col: 61} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 495, Col: 61} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var76) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1772,12 +1767,12 @@ func summarizeModeControl(auto bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var78 string - templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(summarizeModeToggleLabel(auto)) + var templ_7745c5c3_Var77 string + templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.JoinStringErrs(summarizeModeToggleLabel(auto)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 488, Col: 79} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 496, Col: 79} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var77)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1809,21 +1804,21 @@ func ActionButtons(videoID string, active map[string]bool) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var79 := templ.GetChildren(ctx) - if templ_7745c5c3_Var79 == nil { - templ_7745c5c3_Var79 = templ.NopComponent + templ_7745c5c3_Var78 := templ.GetChildren(ctx) + if templ_7745c5c3_Var78 == nil { + templ_7745c5c3_Var78 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "