| 165 | const lyricSegments = useMemo(() => { |
| 166 | const keyCounts = new Map<string, number>(); |
| 167 | const toLyricItem = ( |
| 168 | prefix: "prev" | "curr", |
| 169 | segment: { text: string; cfi?: string | null }, |
| 170 | index: number, |
| 171 | ) => { |
| 172 | const fallbackKey = segment.text.trim().slice(0, 32) || `line-${index}`; |
| 173 | const baseKey = segment.cfi |
| 174 | ? `${prefix}:${segment.cfi}` |
| 175 | : `${prefix}:${index}:${fallbackKey}`; |
| 176 | const occurrence = keyCounts.get(baseKey) ?? 0; |
| 177 | keyCounts.set(baseKey, occurrence + 1); |
| 178 | return { |
| 179 | id: `${baseKey}:${occurrence}`, |
| 180 | text: segment.text, |
| 181 | cfi: segment.cfi ?? null, |
| 182 | }; |
| 183 | }; |
| 184 | |
| 185 | const prev = (prevNarrationSegments ?? []) |
| 186 | .filter((segment) => segment.text.trim().length > 0) |