// Code generated by templ - DO NOT EDIT. // templ: version: v0.3.1020 package web //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import ( "strings" "gitea.d-ma.be/mathias/tapir/internal/adapters/store" ) // Layout is the shared HTML shell. HTMX drives the progressive interactions // (filters, action toggles); every interaction also degrades to a plain form // POST/GET when JS is absent (ui-spec.md §4). func Layout(title string) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var1 := templ.GetChildren(ctx) if templ_7745c5c3_Var1 == nil { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 18, Col: 17} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templ.Raw(styleTag).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
Tapir
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // WelcomePage is the public landing page (served at /welcome, outside the auth // guard — ADR-012). Logged out: the tapir mascot, a one-line tagline, and a // single "Get Started" CTA into the shared Dex flow (sign-in and sign-up are the // same URL). Logged in: a greeting plus links back into the app and to log out. func WelcomePage(user User, loggedIn bool) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var3 := templ.GetChildren(ctx) if templ_7745c5c3_Var3 == nil { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
")
			if templ_7745c5c3_Err != nil {
				return templ_7745c5c3_Err
			}
			templ_7745c5c3_Err = templ.Raw(welcomeHero).Render(ctx, templ_7745c5c3_Buffer)
			if templ_7745c5c3_Err != nil {
				return templ_7745c5c3_Err
			}
			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if loggedIn { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

Welcome back

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if user.Email != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "

Signed in as ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(user.Email) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 47, Col: 57} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, ".

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
Go to my Tapir Log Out
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

Watch less, know more

Tapir summarizes the videos your subscriptions publish, so you can skim the gist and decide what is worth your time.

Get Started

Access is by invitation. If you have an invite link, it will set up your account automatically. Returning users with credentials can log in above.

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — Watch less, know more").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // flashBanner renders a one-shot notification for a flash code (connect success/ // failure, disconnect, delete, registration). An empty or unknown code renders // nothing, so it is safe to drop into any page unconditionally. Reused across the // app — not per-page ad-hoc markup. func flashBanner(code string) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var6 := templ.GetChildren(ctx) if templ_7745c5c3_Var6 == nil { templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) if f, ok := flashFor(code); ok { var templ_7745c5c3_Var7 = []any{"flash", "flash-" + f.Kind} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(f.Message) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 74, Col: 88} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } return nil }) } // ListPage is the full summary list with the filter form. HTMX swaps only the // #summary-list region; a non-HTMX request renders the whole page. flash carries // a one-shot notification (e.g. "connected", "registered") surfaced on arrival // after a POST→redirect. func ListPage(rows []store.SummaryRow, f Filter, flash string, hasConnected bool) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var10 := templ.GetChildren(ctx) if templ_7745c5c3_Var10 == nil { templ_7745c5c3_Var10 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var11 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = flashBanner(flash).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = filterForm(f).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = summaryList(rows, hasConnected).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — Summaries").Render(templ.WithChildren(ctx, templ_7745c5c3_Var11), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } func filterForm(f Filter) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var12 := templ.GetChildren(ctx) if templ_7745c5c3_Var12 == nil { templ_7745c5c3_Var12 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
filtering…
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // summaryList is the swappable list fragment: one card per video (summarized or // not). Cards reflow to a single column on mobile; an empty list shows a friendly // first-run state instead of a blank table. func summaryList(rows []store.SummaryRow, hasConnected bool) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var16 := templ.GetChildren(ctx) if templ_7745c5c3_Var16 == nil { templ_7745c5c3_Var16 = templ.NopComponent } ctx = templ.ClearChildren(ctx) if len(rows) == 0 { if hasConnected { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
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.
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
No videos yet Connect your YouTube account to get started.

Connect YouTube

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } return nil }) } // VideoCard is one list card, also returned standalone by POST /v/{id}/summarize // (HTMX swaps it in place via outerHTML). A summarized video links to its detail // page and shows its provider chip / fallback badge / action state. An // unsummarized video gets a muted "pending" treatment and either a "Summarize" // button (to queue it) or a "Queued" chip when already requested. func VideoCard(r store.SummaryRow) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var17 := templ.GetChildren(ctx) if templ_7745c5c3_Var17 == nil { templ_7745c5c3_Var17 = templ.NopComponent } ctx = templ.ClearChildren(ctx) var templ_7745c5c3_Var18 = []any{"card", templ.KV("card-pending", !r.Summarized)} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if r.Summarized { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var22 string templ_7745c5c3_Var22, 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: 144, Col: 76} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var23 string templ_7745c5c3_Var23, 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: 146, Col: 44} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if cardMeta(r) != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var24 string templ_7745c5c3_Var24, 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: 149, Col: 39} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if r.Summarized { if p := previewText(r.Summary, 160); p != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var25 string templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(p) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 153, Col: 33} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if r.Summarized { if r.AIProvider != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var26 string templ_7745c5c3_Var26, 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: 159, Col: 38} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if r.FallbackUsed { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "fallback") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(r.Actions) > 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var27 string templ_7745c5c3_Var27, 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: 165, Col: 61} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } } else if r.TranscriptStatus == "rate_limited" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "⏳ Retrying later") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else if r.SummarizeRequested { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "Queued waiting for the next run") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "
  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // TapirSpinner is the summarizing animation: a Charmbracelet-style TUI panel — // three richly coloured ASCII tapir frames (inline span colours, snout wiggling // ∩→∪→~) cross-faded by CSS, plus a lipgloss-style progress bar whose mint fill // grows over the dim track. The panel is aria-hidden (decorative); the // "Summarizing…" label below carries the meaning for assistive tech. func TapirSpinner() 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var31 := templ.GetChildren(ctx) if templ_7745c5c3_Var31 == nil { templ_7745c5c3_Var31 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "
    ")
    		if templ_7745c5c3_Err != nil {
    			return templ_7745c5c3_Err
    		}
    		templ_7745c5c3_Err = templ.Raw(tapirFrameHTML1).Render(ctx, templ_7745c5c3_Buffer)
    		if templ_7745c5c3_Err != nil {
    			return templ_7745c5c3_Err
    		}
    		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "
    ")
    		if templ_7745c5c3_Err != nil {
    			return templ_7745c5c3_Err
    		}
    		templ_7745c5c3_Err = templ.Raw(tapirFrameHTML2).Render(ctx, templ_7745c5c3_Buffer)
    		if templ_7745c5c3_Err != nil {
    			return templ_7745c5c3_Err
    		}
    		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "
    ")
    		if templ_7745c5c3_Err != nil {
    			return templ_7745c5c3_Err
    		}
    		templ_7745c5c3_Err = templ.Raw(tapirFrameHTML3).Render(ctx, templ_7745c5c3_Buffer)
    		if templ_7745c5c3_Err != nil {
    			return templ_7745c5c3_Err
    		}
    		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var33 string templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(tapirBarFill) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 197, Col: 99} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "

    Summarizing…

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // processingCard is the in-flight summarization card. It replaces the Summarize // button card and polls /v/{id}/status every 2s, swapping itself (outerHTML, same // id as VideoCard) for whatever state comes back: it keeps polling while still // processing, and the summary/queued card it is eventually replaced by carries no // poll, so polling stops on its own when the fragment changes. func processingCard(r store.SummaryRow) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var34 := templ.GetChildren(ctx) if templ_7745c5c3_Var34 == nil { templ_7745c5c3_Var34 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "
  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var37 string templ_7745c5c3_Var37, 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: 215, Col: 43} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if cardMeta(r) != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var38 string templ_7745c5c3_Var38, 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: 217, Col: 39} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = TapirSpinner().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "
  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // DetailPage is the full summary view: text, highlights, takeaways, metadata, // and the action button group. func DetailPage(r store.SummaryRow) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var39 := templ.GetChildren(ctx) if templ_7745c5c3_Var39 == nil { templ_7745c5c3_Var39 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var40 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var41 string templ_7745c5c3_Var41, 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: 228, Col: 24} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if detailMeta(r) != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var42 string templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(detailMeta(r)) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 231, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if r.FallbackUsed { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "fallback") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if url, ok := embedURL(r.ProviderVideoID); ok { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if r.URL != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "

    watch on source ↗

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = ActionButtons(r.VideoID, actionSet(r.Actions)).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "

    Summary

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var46 string templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(r.Summary) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 255, Col: 31} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(r.Highlights) > 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "

    Highlights

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if len(r.Takeaways) > 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "

    Takeaways

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — "+displayTitle(r)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var40), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // RegisterPage is the explicit registration step (ADR-012): an authenticated Dex // subject with no tapir user picks a display name and accepts the terms to create // their account. errMsg, when set, reports a validation problem on the prior POST. func RegisterPage(email, errMsg string) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var49 := templ.GetChildren(ctx) if templ_7745c5c3_Var49 == nil { templ_7745c5c3_Var49 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var50 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "

    Complete your registration

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if email != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "

    Signed in as ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var51 string templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(email) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 289, Col: 40} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, ".

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "

    Choose a display name to finish setting up your Tapir account.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if errMsg != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var52 string templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(errMsg) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 293, Col: 42} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — Register").Render(templ.WithChildren(ctx, templ_7745c5c3_Var50), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // InvitePage is the public set-password form an invited user reaches via their // emailed /invite/{token} link. The email is shown read-only (it is fixed by the // invite, not chosen here); the visitor sets a password to create their account. // errMsg, when set, reports a validation problem on the prior submit. No auth // chrome (header nav) is appropriate — the visitor has no session yet — but the // shared Layout keeps the look consistent. func InvitePage(email, token, errMsg string) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var53 := templ.GetChildren(ctx) if templ_7745c5c3_Var53 == nil { templ_7745c5c3_Var53 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var54 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "

    Set up your Tapir account

    Invitation for ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var55 string templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(email) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 320, Col: 41} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, ".

    Choose a password to finish creating your account. You'll then log in with this email and password.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if errMsg != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var56 string templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinStringErrs(errMsg) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 323, Col: 42} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — Set your password").Render(templ.WithChildren(ctx, templ_7745c5c3_Var54), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // InviteInvalidPage is shown when an invite token is missing, expired, or already // used — a dead-end with no form, so a stale or replayed link reads clearly. func InviteInvalidPage() 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var59 := templ.GetChildren(ctx) if templ_7745c5c3_Var59 == nil { templ_7745c5c3_Var59 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var60 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "

    This invite link is no longer valid

    This invitation has expired or has already been used. Ask for a fresh invite link, or log in if you already have an account.

    Log in

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — Invitation").Render(templ.WithChildren(ctx, templ_7745c5c3_Var60), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // InviteNoticePage is a terminal message after a submit that neither succeeded nor // is a retryable validation error (account already exists, RBAC missing, or the // dev "deployed-only" degrade). showLogin adds a log-in CTA where that is the // natural next step. func InviteNoticePage(message string, showLogin bool) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var61 := templ.GetChildren(ctx) if templ_7745c5c3_Var61 == nil { templ_7745c5c3_Var61 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var62 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "

    Invitation

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var63 string templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(message) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 364, Col: 15} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if showLogin { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "

    Log in

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — Invitation").Render(templ.WithChildren(ctx, templ_7745c5c3_Var62), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // AccountPage is the account-management view: the registered display name and // signed-in email, the user's connected video accounts (each with a Disconnect // control), a Connect-YouTube link when none is connected, and the delete-account // danger zone. flash surfaces a one-shot notification (disconnect/connect). func AccountPage(displayName, email string, conns []store.Connection, autoSummarize bool, flash string) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var64 := templ.GetChildren(ctx) if templ_7745c5c3_Var64 == nil { templ_7745c5c3_Var64 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var65 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = flashBanner(flash).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "

    Account

    Display name
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var66 string templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(displayNameOr(displayName)) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 383, Col: 36} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if email != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "
    Signed in as
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var67 string templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.JoinStringErrs(email) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views.templ`, Line: 386, Col: 16} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var67)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "

    Summarization

    Automatic summarizes every new video as it is discovered. Manual lets you pick which videos to summarize — new videos appear in your list with a Summarize button.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = summarizeModeControl(autoSummarize).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "

    Connected accounts

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(conns) == 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "

    No connected video accounts yet.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if !hasYouTube(conns) { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "

    Connect YouTube

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "

    Delete account

    Permanently remove your Tapir account and all of its data — summaries, watch/skip/save actions, and connected accounts. This cannot be undone.

    Delete account…

    This permanently deletes your account and all data. Are you sure?

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Tapir — Account").Render(templ.WithChildren(ctx, templ_7745c5c3_Var65), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // summarizeModeControl is the auto/manual toggle, also returned standalone by // POST /account/summarize-mode (HTMX swaps it via outerHTML). The hidden field // submits the desired NEW value, so a single submit flips the mode; without JS the // form posts and the handler redirects back to /account. func summarizeModeControl(auto bool) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var73 := templ.GetChildren(ctx) if templ_7745c5c3_Var73 == nil { templ_7745c5c3_Var73 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "

    Current mode: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var74 string templ_7745c5c3_Var74, 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: 451, Col: 53} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // ActionButtons is the toggle group fragment returned by POST /v/{id}/action. // Each button submits its verb; HTMX swaps this element in place (outerHTML), // and without JS the form POSTs and the handler redirects back to the detail // page. active marks the verbs currently set for (user, video). func ActionButtons(videoID string, active map[string]bool) 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 if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var77 := templ.GetChildren(ctx) if templ_7745c5c3_Var77 == nil { templ_7745c5c3_Var77 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, v := range actionVerbs { var templ_7745c5c3_Var80 = []any{"action", templ.KV("active", active[v])} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var80...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } var _ = templruntime.GeneratedTemplate