mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 06:25:20 +00:00
64 lines
2 KiB
TypeScript
64 lines
2 KiB
TypeScript
'use client'
|
|
|
|
import { SpeechHighlightParts } from '@/components/campaign/speech/SpeechHighlightParts'
|
|
import type { SpeechHighlightPart } from '@/lib/speechHighlight'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
/**
|
|
* The only contract a transcript line needs: it is structural on purpose, so
|
|
* the Câmara/detail VMs of every acervo source (C200 recordings, C216 web
|
|
* speeches) share one clickable segment without a twin.
|
|
*/
|
|
type TranscriptSegment = {
|
|
startSeconds: number
|
|
startLabel: string
|
|
parts: readonly SpeechHighlightPart[]
|
|
}
|
|
|
|
/**
|
|
* C200 — the clickable transcript line shared by the plain C199 list, the
|
|
* grouped C200 blocks and the C216 web detail: seeks the player to the segment
|
|
* and renders the search highlight. `variant` keeps the approved
|
|
* paddings/sizes without a twin — the web artifact marks the active segment
|
|
* with the red left border while the recordings keep the neutral fill.
|
|
*/
|
|
export const CampaignTranscriptSegmentButton = ({
|
|
segment,
|
|
active,
|
|
variant = 'plain',
|
|
onSeek,
|
|
}: {
|
|
segment: TranscriptSegment
|
|
active: boolean
|
|
variant?: 'plain' | 'grouped' | 'web'
|
|
onSeek: (seconds: number) => void
|
|
}) => (
|
|
<button
|
|
type="button"
|
|
data-start-seconds={segment.startSeconds}
|
|
onClick={() => onSeek(segment.startSeconds)}
|
|
className={cn(
|
|
'grid w-full grid-cols-[3.25rem_1fr] gap-3 text-left transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
variant === 'grouped' ? 'px-3 py-2.5' : 'rounded-lg px-2 py-1.5',
|
|
active && (variant === 'web' ? 'border-l-2 border-primary bg-primary/[0.08]' : 'bg-muted'),
|
|
)}
|
|
>
|
|
<span
|
|
className={cn(
|
|
'text-xs tabular-nums',
|
|
variant === 'plain' && 'pt-0.5',
|
|
active ? 'text-primary' : 'text-muted-foreground',
|
|
)}
|
|
>
|
|
{segment.startLabel}
|
|
</span>
|
|
<span
|
|
className={cn(
|
|
'text-sm text-foreground/90',
|
|
variant === 'grouped' ? 'leading-5' : 'leading-relaxed',
|
|
)}
|
|
>
|
|
<SpeechHighlightParts parts={segment.parts} />
|
|
</span>
|
|
</button>
|
|
)
|