🚧(frontend) debug transcript segment organization
for the big monday demo, push a draft commit.
This commit is contained in:
committed by
aleb_the_flash
parent
a5254ffd59
commit
b675517a60
@@ -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} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user