package web import ( "fmt" "time" "git.d-ma.be/mathias/tapir/internal/domain" "git.d-ma.be/mathias/tapir/internal/uploads" ) // UploadsPage is the upload form plus the caller's own uploads (ADR-033). templ UploadsPage(v uploadsView) { @Layout("Tapir — Upload a recording") {

Upload a recording

Audio only. Up to { fmt.Sprintf("%d MB", v.Limits.MaxBytes>>20) } and { uploads.FormatDuration(v.Limits.MaxDuration) }. The transcript is private to you; the audio is deleted once it has been transcribed.

if v.Error != "" { }

if len(v.Rows) > 0 {

Your recordings

}
} } // UploadPage is one upload's page: its title and the polling status region. templ UploadPage(u domain.UploadedTranscript, chatEnabled bool) { @Layout("Tapir — " + u.Title) {

{ u.Title }

@uploadStatus(u, chatEnabled)

All recordings

} } // uploadStatus is the region HTMX polls. Unfinished states carry hx-trigger so the // page re-asks; done and failed render without it, so nothing polls forever. templ uploadStatus(u domain.UploadedTranscript, chatEnabled bool) { switch u.Status { case domain.UploadDone:

Transcribed { uploads.FormatDuration(time.Duration(u.AudioSeconds * float64(time.Second))) } of audio by { u.Endpoint }.

if chatEnabled {

Ask about this recording

}
Transcript
{ u.Content }
case domain.UploadFailed: default:
if u.Status == domain.UploadTranscribing {

Transcribing… a long recording takes a few minutes.

} else {

Queued — waiting for its turn to be transcribed.

}
} } // UploadChatPage is the no-JS full page for chatting with an uploaded transcript: // the same chat panel as a video's (ADR-027), scoped to this recording. templ UploadChatPage(u domain.UploadedTranscript, v chatView) { @Layout("Tapir — Ask about " + u.Title) {

{ u.Title }

Ask about this recording

Answers come only from this recording's transcript, which is private to you.

@chatPanel(v)

Back to the transcript

} }