🚧(frontend) debug transcript segment organization

for the big monday demo, push a draft commit.
This commit is contained in:
lebaudantoine
2026-01-23 19:39:24 +01:00
committed by aleb_the_flash
parent a5254ffd59
commit b675517a60

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { useSubtitles } from '../hooks/useSubtitles' import { useSubtitles } from '../hooks/useSubtitles'
import { css, cva } from '@/styled-system/css' import { css, cva } from '@/styled-system/css'
import { styled } from '@/styled-system/jsx' import { styled } from '@/styled-system/jsx'
@@ -20,6 +20,11 @@ export interface TranscriptionSegment {
lastReceivedTime: number lastReceivedTime: number
} }
export interface TranscriptionSegmentWithParticipant
extends TranscriptionSegment {
participant: Participant
}
export interface TranscriptionRow { export interface TranscriptionRow {
id: string id: string
participant: Participant participant: Participant
@@ -30,88 +35,41 @@ export interface TranscriptionRow {
} }
const useTranscriptionState = () => { const useTranscriptionState = () => {
const [transcriptionRows, setTranscriptionRows] = useState< const [transcriptionSegments, setTranscriptionSegments] = useState<
TranscriptionRow[] TranscriptionSegmentWithParticipant[]
>([]) >([])
const [lastActiveParticipantIdentity, setLastActiveParticipantIdentity] =
useState<string | null>(null)
const updateTranscriptions = ( const updateTranscriptionSegments = (
segments: TranscriptionSegment[], segments: TranscriptionSegment[],
participant?: Participant participant?: Participant
) => { ) => {
console.log(participant, segments) console.log(participant, segments)
if (!participant || segments.length === 0) return if (!participant || segments.length === 0) return
setTranscriptionRows((prevRows) => { if (segments.length > 1) {
const updatedRows = [...prevRows] console.warn('Unexpected error more segments')
const now = Date.now() return
}
const shouldAppendToLastRow = const segment = segments[0]
lastActiveParticipantIdentity === participant.identity &&
updatedRows.length > 0
if (shouldAppendToLastRow) { setTranscriptionSegments((prevSegments) => {
const lastRowIndex = updatedRows.length - 1 const existingSegmentIds = new Set(prevSegments.map((s) => s.id))
const lastRow = updatedRows[lastRowIndex] if (existingSegmentIds.has(segment.id)) return prevSegments
return [
const existingSegmentIds = new Set(lastRow.segments.map((s) => s.id)) ...prevSegments,
const newSegments = segments.filter( {
(segment) => !existingSegmentIds.has(segment.id) participant: participant,
) ...segment,
const updatedSegments = lastRow.segments.map((existing) => { },
const update = segments.find((s) => s.id === existing.id) ]
return update && update.final ? update : existing
})
updatedRows[lastRowIndex] = {
...lastRow,
segments: [...updatedSegments, ...newSegments],
lastUpdateTime: now,
}
} else {
const newRow: TranscriptionRow = {
id: `${participant.identity}-${now}`,
participant,
segments: [...segments],
lastReceivedTime: Math.min(
...segments.map((s) => s.lastReceivedTime)
),
lastUpdateTime: now,
}
updatedRows.push(newRow)
}
return updatedRows
})
setLastActiveParticipantIdentity(participant.identity)
}
const clearTranscriptions = () => {
setTranscriptionRows([])
setLastActiveParticipantIdentity(null)
}
const updateParticipant = (_name: string, participant: Participant) => {
setTranscriptionRows((prevRows) => {
return prevRows.map((row) => {
if (row.participant.identity === participant.identity) {
return {
...row,
participant,
}
}
return row
})
}) })
} }
return { return {
transcriptionRows, updateTranscriptionSegments,
updateTranscriptions, transcriptionSegments,
clearTranscriptions,
updateParticipant,
} }
} }
@@ -196,24 +154,54 @@ const SubtitlesWrapper = styled(
export const Subtitles = () => { export const Subtitles = () => {
const { areSubtitlesOpen } = useSubtitles() const { areSubtitlesOpen } = useSubtitles()
const room = useRoomContext() const room = useRoomContext()
const { transcriptionRows, updateTranscriptions, updateParticipant } =
const { transcriptionSegments, updateTranscriptionSegments } =
useTranscriptionState() useTranscriptionState()
useEffect(() => { useEffect(() => {
if (!room) return if (!room) return
room.on(RoomEvent.TranscriptionReceived, updateTranscriptions) room.on(RoomEvent.TranscriptionReceived, updateTranscriptionSegments)
return () => { return () => {
room.off(RoomEvent.TranscriptionReceived, updateTranscriptions) room.off(RoomEvent.TranscriptionReceived, updateTranscriptionSegments)
} }
}, [room, updateTranscriptions]) }, [room, updateTranscriptionSegments])
useEffect(() => { const transcriptionRows = useMemo(() => {
if (!room) return if (transcriptionSegments.length === 0) return []
room.on(RoomEvent.ParticipantNameChanged, updateParticipant)
return () => { const rows: TranscriptionRow[] = []
room.off(RoomEvent.ParticipantNameChanged, updateParticipant) let currentRow: TranscriptionRow | null = null
for (const segment of transcriptionSegments) {
const shouldStartNewRow =
!currentRow ||
currentRow.participant.identity !== segment.participant.identity
if (shouldStartNewRow) {
currentRow = {
id: `${segment.participant.identity}-${segment.firstReceivedTime}`,
participant: segment.participant,
segments: [segment],
startTime: segment.startTime,
lastUpdateTime: segment.lastReceivedTime,
lastReceivedTime: segment.lastReceivedTime,
}
rows.push(currentRow)
} else if (currentRow) {
currentRow.segments.push(segment)
currentRow.lastUpdateTime = Math.max(
currentRow.lastUpdateTime,
segment.lastReceivedTime
)
currentRow.lastReceivedTime = Math.max(
currentRow.lastReceivedTime,
segment.lastReceivedTime
)
}
} }
}, [room, updateParticipant])
return rows
}, [transcriptionSegments])
return ( return (
<SubtitlesWrapper areOpen={areSubtitlesOpen}> <SubtitlesWrapper areOpen={areSubtitlesOpen}>
@@ -232,11 +220,7 @@ export const Subtitles = () => {
> >
{transcriptionRows {transcriptionRows
.slice() .slice()
.sort( .reverse()
(a, b) =>
(b.startTime ?? b.lastUpdateTime) -
(a.startTime ?? a.lastUpdateTime)
)
.map((row) => ( .map((row) => (
<Transcription key={row.id} row={row} /> <Transcription key={row.id} row={row} />
))} ))}