kasunk99-livestream-core 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -16,8 +16,16 @@ export type UseHostSocketOptions = {
|
|
|
16
16
|
/** App-level user ID forwarded to the server on join-room (optional). */
|
|
17
17
|
hostUserId?: string;
|
|
18
18
|
};
|
|
19
|
+
export type HostChatMessage = {
|
|
20
|
+
id: string;
|
|
21
|
+
displayName: string;
|
|
22
|
+
text: string;
|
|
23
|
+
timestamp: number;
|
|
24
|
+
};
|
|
19
25
|
export type UseHostSocketReturn = HostState & {
|
|
26
|
+
chatMessages: HostChatMessage[];
|
|
20
27
|
setDisplayName: (name: string) => void;
|
|
28
|
+
sendChatMessage: (text: string) => void;
|
|
21
29
|
startPreview: () => Promise<void>;
|
|
22
30
|
stopPreview: () => void;
|
|
23
31
|
startLive: () => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHostSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useHostSocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAoB3B,MAAM,MAAM,oBAAoB,GAAG;IACjC,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAC5C,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC;AAMF,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"useHostSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useHostSocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAoB3B,MAAM,MAAM,oBAAoB,GAAG;IACjC,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAC5C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC;AAMF,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CA4nBrF"}
|
|
@@ -36,6 +36,7 @@ export function useHostSocket(options = {}) {
|
|
|
36
36
|
// Subscribe to module-level state so all hook instances stay in sync
|
|
37
37
|
// and the state survives remount (tab navigation).
|
|
38
38
|
const [state, setLocalState] = useState(getHostState);
|
|
39
|
+
const [chatMessages, setChatMessages] = useState([]);
|
|
39
40
|
useEffect(() => {
|
|
40
41
|
// If the store has a streamURL but our local copy doesn't (fresh mount),
|
|
41
42
|
// restore it from the active stream so the preview shows immediately.
|
|
@@ -107,6 +108,7 @@ export function useHostSocket(options = {}) {
|
|
|
107
108
|
}
|
|
108
109
|
catch { /* ignore */ }
|
|
109
110
|
resetHostState();
|
|
111
|
+
setChatMessages([]);
|
|
110
112
|
// Step 3 — stop tracks deferred: give the executor a moment to finish pc.close().
|
|
111
113
|
// Screen stream: use release() not t.stop(). release() calls TrackPrivate.dispose()
|
|
112
114
|
// → ScreenCaptureController.dispose() → MediaProjectionService.abort() +
|
|
@@ -181,6 +183,36 @@ export function useHostSocket(options = {}) {
|
|
|
181
183
|
socket.off('ice-servers', onIceServers);
|
|
182
184
|
};
|
|
183
185
|
}, [fullCleanup]);
|
|
186
|
+
// ── Chat subscription ──────────────────────────────────────────────────────
|
|
187
|
+
// Registered on a separate effect keyed to live state so it is guaranteed to
|
|
188
|
+
// be active only while the host is in the room (socket.join runs as part of
|
|
189
|
+
// startLive). Registering it in the socket setup effect is too early — the host
|
|
190
|
+
// has not joined the room yet, and reconnects after navigate-away clear the
|
|
191
|
+
// room membership, so we need to re-register on every live transition.
|
|
192
|
+
useEffect(() => {
|
|
193
|
+
if (!state.live) {
|
|
194
|
+
setChatMessages([]);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const socket = hostSession.socket;
|
|
198
|
+
if (!socket)
|
|
199
|
+
return;
|
|
200
|
+
const onChatMessage = (msg) => {
|
|
201
|
+
if (!msg || typeof msg !== 'object')
|
|
202
|
+
return;
|
|
203
|
+
const m = msg;
|
|
204
|
+
const text = typeof m.text === 'string' ? m.text.trim() : '';
|
|
205
|
+
if (!text)
|
|
206
|
+
return;
|
|
207
|
+
const displayName = typeof m.displayName === 'string' ? m.displayName : 'User';
|
|
208
|
+
const timestamp = typeof m.timestamp === 'number' ? m.timestamp : Date.now();
|
|
209
|
+
const id = `${String(m.peerId ?? 'p')}-${timestamp}-${text.slice(0, 6)}`;
|
|
210
|
+
setChatMessages((prev) => [...prev.slice(-99), { id, displayName, text, timestamp }]);
|
|
211
|
+
};
|
|
212
|
+
socket.on('chat-message', onChatMessage);
|
|
213
|
+
return () => { socket.off('chat-message', onChatMessage); };
|
|
214
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
215
|
+
}, [state.live]);
|
|
184
216
|
// ── Permissions ────────────────────────────────────────────────────────────
|
|
185
217
|
const requestCameraMicPermissions = useCallback(async () => {
|
|
186
218
|
if (Platform.OS !== 'android')
|
|
@@ -545,9 +577,17 @@ export function useHostSocket(options = {}) {
|
|
|
545
577
|
const setDisplayName = useCallback((name) => {
|
|
546
578
|
patchHostState({ displayName: name });
|
|
547
579
|
}, []);
|
|
580
|
+
const sendChatMessage = useCallback((text) => {
|
|
581
|
+
const trimmed = text.trim();
|
|
582
|
+
if (!trimmed || !hostSession.socket?.connected)
|
|
583
|
+
return;
|
|
584
|
+
hostSession.socket.emit('chat-message', { text: trimmed });
|
|
585
|
+
}, []);
|
|
548
586
|
return {
|
|
549
587
|
...state,
|
|
588
|
+
chatMessages,
|
|
550
589
|
setDisplayName,
|
|
590
|
+
sendChatMessage,
|
|
551
591
|
startPreview,
|
|
552
592
|
stopPreview,
|
|
553
593
|
startLive,
|
package/package.json
CHANGED