forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRecordingController.tsx
More file actions
103 lines (91 loc) · 2.78 KB
/
Copy pathRecordingController.tsx
File metadata and controls
103 lines (91 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'use client';
import { useEffect, useRef } from 'react';
import { useRecording } from '@/hooks/useRecording';
import { useRecordingContext } from './RecordingContext';
import {
createRecordingChannel,
broadcastStateUpdate,
broadcastSegmentsUpdate,
type RecordingBroadcastMessage,
} from '@/lib/recordingBroadcast';
/**
* Controller component that initializes recording hooks and broadcast communication.
* Should be mounted once inside RecordingProvider.
* This ensures handlers are registered consistently.
*/
export function RecordingController() {
// Initialize recording hooks - this registers the action handlers with context
useRecording();
// Get context for broadcasting
const {
state,
audioMode,
segments,
duration,
micLevel,
systemLevel,
startRecording,
pauseRecording,
resumeRecording,
stopRecording,
} = useRecordingContext();
const channelRef = useRef<BroadcastChannel | null>(null);
// Initialize broadcast channel
useEffect(() => {
const channel = createRecordingChannel();
if (!channel) return;
channelRef.current = channel;
// Handle messages from pop-out windows
// eslint-disable-next-line @typescript-eslint/no-explicit-any
channel.onmessage = (event: MessageEvent<any>) => {
const message = event.data;
switch (message.type) {
case 'command':
if (message.command === 'start') {
// Pass audio mode directly to startRecording to avoid race condition
startRecording(message.audioMode);
} else if (message.command === 'pause') pauseRecording();
else if (message.command === 'resume') resumeRecording();
else if (message.command === 'stop') stopRecording();
break;
case 'request-state':
// Send current state to the requesting window
broadcastStateUpdate(
channel,
state,
audioMode,
duration,
micLevel,
systemLevel,
);
broadcastSegmentsUpdate(channel, segments);
break;
}
};
return () => {
channel.close();
channelRef.current = null;
};
}, [startRecording, pauseRecording, resumeRecording, stopRecording]);
// Broadcast state updates when state changes
useEffect(() => {
if (channelRef.current) {
broadcastStateUpdate(
channelRef.current,
state,
audioMode,
duration,
micLevel,
systemLevel,
);
}
}, [state, audioMode, duration, micLevel, systemLevel]);
// Broadcast segments updates when segments change
useEffect(() => {
if (channelRef.current) {
broadcastSegmentsUpdate(channelRef.current, segments);
}
}, [segments]);
// This component doesn't render anything
return null;
}