app/src/utils/tldraw/cc-base/cc-transcription/TranscriptionManager.ts
CC Worker 765573163d feat(ts): R4 TypeScript hardening H1-H6 — reduce errors 177→152
H1: CCGraphNavPanel — useMemo import + LogCategory fix
H2: CCTimetableLessonNodeShapeUtil — props type alignment (cc-graph-props.ts)
H3: cc-graph-shapes — add missing CCTimetableLessonNode* import (was never imported)
H4: CCNodeSnapshotPanel — RestartAlt import from @mui/icons-material
H5: CCExamMarkerPanel + CCFilesPanelEnhanced — BlobPart cast + webkitdirectory @ts-ignore
H6: TranscriptionManager — setTranscriptionCallback interface fix
Plus: CCExportPdfButton BlobPart cast, SimpleUploadTest icon imports, graph-sidebar LogCategory

tsc before: 177 (master)
tsc after:  152 (reduction of 25 errors, well below 160 acceptable threshold)
2026-06-01 02:29:38 +00:00

77 lines
2.7 KiB
TypeScript

import { Editor, TLShapeId } from '@tldraw/tldraw';
import { TranscriptionService } from './transcriptionService';
import { CCLiveTranscriptionShapeUtil } from './CCLiveTranscriptionShapeUtil';
export class TranscriptionManager {
private static instances = new WeakMap<Editor, TranscriptionManager>();
private transcriptionService?: TranscriptionService;
private currentShapeId?: TLShapeId;
private sameOutputCount = 0;
private lastText = '';
private readonly SAME_OUTPUT_THRESHOLD = 10;
constructor(private editor: Editor) {}
static getManager(editor: Editor): TranscriptionManager {
let manager = TranscriptionManager.instances.get(editor);
if (!manager) {
manager = new TranscriptionManager(editor);
TranscriptionManager.instances.set(editor, manager);
}
return manager;
}
startTranscription(shapeId: TLShapeId) {
console.log('Starting transcription...');
this.currentShapeId = shapeId;
this.transcriptionService = new TranscriptionService();
// Set up callback for transcription updates
this.transcriptionService.setServerSegmentsCallback((segments: Array<{ text: string; start: number; end: number }>, isLastLive: boolean) => {
console.log('📝 Transcription update received:', { segments: segments.length, isLastLive });
const util = this.editor.getShapeUtil<CCLiveTranscriptionShapeUtil>('cc-live-transcription');
if (!util) {
console.warn('❌ Shape util not found');
return;
}
console.log('Found transcription util:', !!util);
const text = segments.map(s => s.text).join('') || '';
const metadata = segments.length ? { start: segments[0].start, end: segments[segments.length - 1].end } : { start: 0, end: 0 };
const isFinal = isLastLive;
// Check if text is stable (same output multiple times)
const isStable = text === this.lastText;
if (isStable) {
this.sameOutputCount++;
} else {
this.sameOutputCount = 0;
this.lastText = text;
}
// Mark as completed if we've seen the same output multiple times or if marked as final
const isCompleted = isFinal || this.sameOutputCount >= this.SAME_OUTPUT_THRESHOLD;
util.updateText(
this.currentShapeId!,
text,
isCompleted,
metadata
);
});
// Start the transcription service
this.transcriptionService.startTranscription();
}
stopTranscription() {
console.log('Stopping transcription...');
if (this.transcriptionService) {
this.transcriptionService.stopTranscription();
this.transcriptionService = undefined;
}
this.currentShapeId = undefined;
this.sameOutputCount = 0;
this.lastText = '';
}
}