kasunk99-livestream-core 0.2.7 → 0.2.9
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAa1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/C,KAAK,yBAAyB,GAAG;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAgBF;;GAEG;AACH,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAa1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/C,KAAK,yBAAyB,GAAG;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAgBF;;GAEG;AACH,eAAO,MAAM,oBAAoB,uDAyS/B,CAAC"}
|
|
@@ -158,7 +158,7 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
|
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
};
|
|
161
|
-
return (_jsxs(View, { style: styles.container, children: [showVideo && RTCViewComponent && streamURL ? (_jsx(RTCViewComponent, { streamURL: streamURL, stream: displayStream, style: styles.rtcView, objectFit: "contain", mirror: false }, `rtc-${trackCount}-${streamURL}`)) : (_jsxs(View, { style: styles.videoPlaceholder, children: [joining && _jsx(Text, { style: styles.placeholderText, children: "Joining..." }), error && _jsx(Text, { style: [styles.placeholderText, styles.errorText], children: error }), joined && !joining && !error && (_jsxs(_Fragment, { children: [_jsx(Text, { style: styles.liveBadge, children: "LIVE" }), _jsx(Text, { style: styles.placeholderText, children: stream.roomId }), hasVideo && webrtcUnavailable && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Video needs a development build.", '\n', "Run: npx expo run:android"] })), hasVideo && consumeError && (_jsx(Text, { style: [styles.hintText, styles.errorText], children: consumeError })), hasVideo && !remoteStream && !webrtcUnavailable && !consumeError && (_jsx(Text, { style: styles.hintText, children: "Loading video..." })), !hasVideo && joined && producerList.length === 0 && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Host has not started camera yet.", '\n', "Use a web client to stream, or wait for host to produce."] })), hasVideo && remoteStream && !RTCViewComponent && (_jsx(Text, { style: styles.hintText, children: "Video received (use dev build to see it)" })), hasVideo && remoteStream && RTCViewComponent && !hasVideoTrack && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Audio only (no video track yet)" })), hasVideo && remoteStream && hasVideoTrack && !streamURL && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Video track received but cannot display (need dev build with react-native-webrtc)" }))] }))] })), _jsxs(View, { style: styles.overlay, children: [_jsxs(View, { style: styles.topMeta, children: [_jsx(View, { style: styles.row, children: _jsxs(Text, { style: styles.roomId, numberOfLines: 1, children: ["LIVE \u00B7 ", stream.hostDisplayName || stream.title || stream.roomId] }) }),
|
|
161
|
+
return (_jsxs(View, { style: styles.container, children: [showVideo && RTCViewComponent && streamURL ? (_jsx(RTCViewComponent, { streamURL: streamURL, stream: displayStream, style: styles.rtcView, objectFit: "contain", mirror: false }, `rtc-${trackCount}-${streamURL}`)) : (_jsxs(View, { style: styles.videoPlaceholder, children: [joining && _jsx(Text, { style: styles.placeholderText, children: "Joining..." }), error && _jsx(Text, { style: [styles.placeholderText, styles.errorText], children: error }), joined && !joining && !error && (_jsxs(_Fragment, { children: [_jsx(Text, { style: styles.liveBadge, children: "LIVE" }), _jsx(Text, { style: styles.placeholderText, children: stream.roomId }), hasVideo && webrtcUnavailable && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Video needs a development build.", '\n', "Run: npx expo run:android"] })), hasVideo && consumeError && (_jsx(Text, { style: [styles.hintText, styles.errorText], children: consumeError })), hasVideo && !remoteStream && !webrtcUnavailable && !consumeError && (_jsx(Text, { style: styles.hintText, children: "Loading video..." })), !hasVideo && joined && producerList.length === 0 && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Host has not started camera yet.", '\n', "Use a web client to stream, or wait for host to produce."] })), hasVideo && remoteStream && !RTCViewComponent && (_jsx(Text, { style: styles.hintText, children: "Video received (use dev build to see it)" })), hasVideo && remoteStream && RTCViewComponent && !hasVideoTrack && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Audio only (no video track yet)" })), hasVideo && remoteStream && hasVideoTrack && !streamURL && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Video track received but cannot display (need dev build with react-native-webrtc)" }))] }))] })), _jsxs(View, { style: styles.overlay, children: [_jsxs(View, { style: styles.topMeta, children: [_jsx(View, { style: styles.row, children: _jsxs(Text, { style: styles.roomId, numberOfLines: 1, children: ["LIVE \u00B7 ", stream.hostDisplayName || stream.title || stream.roomId] }) }), _jsx(View, { style: styles.stats, children: _jsxs(Text, { style: styles.statsText, children: ["\uD83D\uDC41 ", viewerCount] }) })] }), _jsx(View, { style: [styles.chatPanel, keyboardHeight > 0 && { bottom: 16 + keyboardHeight }], pointerEvents: "box-none", children: _jsxs(ScrollView, { scrollEnabled: false, keyboardShouldPersistTaps: "always", contentContainerStyle: styles.chatStack, children: [_jsx(View, { style: styles.chatListWrapper, children: _jsx(ScrollView, { ref: chatListRef, contentContainerStyle: styles.chatListContent, showsVerticalScrollIndicator: false, keyboardDismissMode: "on-drag", keyboardShouldPersistTaps: "always", nestedScrollEnabled: true, children: chatData.map((item) => (_jsxs(Text, { style: styles.chatLine, numberOfLines: 2, children: [_jsx(Text, { style: [styles.chatName, { color: getNameColor(item.displayName) }], children: item.displayName }), _jsxs(Text, { style: styles.chatText, children: [" ", item.text] })] }, item.id))) }) }), _jsxs(View, { style: styles.chatInputRow, children: [_jsx(TextInput, { style: styles.chatInput, value: chatInput, onChangeText: setChatInput, placeholder: joined ? 'Say something...' : 'Connecting...', placeholderTextColor: "#9ca3af", editable: joined && !joining && !error, onSubmitEditing: sendChat, returnKeyType: "send" }), _jsx(TouchableOpacity, { onPress: sendChat, disabled: !joined || joining || !!error || !chatInput.trim(), style: [
|
|
162
162
|
styles.chatSendButton,
|
|
163
163
|
(!joined || joining || !!error || !chatInput.trim()) && styles.chatSendButtonDisabled,
|
|
164
164
|
], children: _jsx(Text, { style: styles.chatSendText, children: "\u27A4" }) })] })] }) })] })] }));
|
|
@@ -16,7 +16,14 @@ 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;
|
|
21
28
|
startPreview: () => Promise<void>;
|
|
22
29
|
stopPreview: () => 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,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,CAmmBrF"}
|
|
@@ -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() +
|
|
@@ -170,15 +172,29 @@ export function useHostSocket(options = {}) {
|
|
|
170
172
|
const onIceServers = (servers) => {
|
|
171
173
|
hostSession.iceServers = Array.isArray(servers) ? servers : [];
|
|
172
174
|
};
|
|
175
|
+
const onChatMessage = (msg) => {
|
|
176
|
+
if (!msg || typeof msg !== 'object')
|
|
177
|
+
return;
|
|
178
|
+
const m = msg;
|
|
179
|
+
const text = typeof m.text === 'string' ? m.text.trim() : '';
|
|
180
|
+
if (!text)
|
|
181
|
+
return;
|
|
182
|
+
const displayName = typeof m.displayName === 'string' ? m.displayName : 'User';
|
|
183
|
+
const timestamp = typeof m.timestamp === 'number' ? m.timestamp : Date.now();
|
|
184
|
+
const id = `${String(m.peerId ?? 'p')}-${timestamp}-${text.slice(0, 6)}`;
|
|
185
|
+
setChatMessages((prev) => [...prev.slice(-99), { id, displayName, text, timestamp }]);
|
|
186
|
+
};
|
|
173
187
|
socket.on('connect', onConnect);
|
|
174
188
|
socket.on('connect_error', onConnectError);
|
|
175
189
|
socket.on('disconnect', onDisconnect);
|
|
176
190
|
socket.on('ice-servers', onIceServers);
|
|
191
|
+
socket.on('chat-message', onChatMessage);
|
|
177
192
|
return () => {
|
|
178
193
|
socket.off('connect', onConnect);
|
|
179
194
|
socket.off('connect_error', onConnectError);
|
|
180
195
|
socket.off('disconnect', onDisconnect);
|
|
181
196
|
socket.off('ice-servers', onIceServers);
|
|
197
|
+
socket.off('chat-message', onChatMessage);
|
|
182
198
|
};
|
|
183
199
|
}, [fullCleanup]);
|
|
184
200
|
// ── Permissions ────────────────────────────────────────────────────────────
|
|
@@ -547,6 +563,7 @@ export function useHostSocket(options = {}) {
|
|
|
547
563
|
}, []);
|
|
548
564
|
return {
|
|
549
565
|
...state,
|
|
566
|
+
chatMessages,
|
|
550
567
|
setDisplayName,
|
|
551
568
|
startPreview,
|
|
552
569
|
stopPreview,
|
package/package.json
CHANGED