@streamplace/components 0.7.0 → 0.7.2
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.
- package/dist/components/chat/chat-box.js +46 -43
- package/dist/components/chat/chat-message.js +36 -33
- package/dist/components/chat/chat.js +31 -27
- package/dist/components/chat/mention-suggestions.js +16 -13
- package/dist/components/chat/mod-view.js +20 -17
- package/dist/components/mobile-player/fullscreen.js +21 -17
- package/dist/components/mobile-player/fullscreen.native.js +39 -35
- package/dist/components/mobile-player/player.js +38 -32
- package/dist/components/mobile-player/props.js +2 -1
- package/dist/components/mobile-player/shared.js +16 -13
- package/dist/components/mobile-player/ui/countdown.js +23 -19
- package/dist/components/mobile-player/ui/index.js +9 -5
- package/dist/components/mobile-player/ui/input.js +16 -12
- package/dist/components/mobile-player/ui/metrics.js +20 -16
- package/dist/components/mobile-player/ui/streamer-context-menu.js +6 -3
- package/dist/components/mobile-player/ui/viewer-context-menu.js +19 -16
- package/dist/components/mobile-player/ui/viewers.js +23 -0
- package/dist/components/mobile-player/use-webrtc.js +29 -24
- package/dist/components/mobile-player/video.js +109 -99
- package/dist/components/mobile-player/video.native.js +108 -84
- package/dist/components/mobile-player/webrtc-diagnostics.js +9 -5
- package/dist/components/mobile-player/webrtc-primitives.js +8 -6
- package/dist/components/mobile-player/webrtc-primitives.native.js +8 -1
- package/dist/components/ui/button.js +26 -23
- package/dist/components/ui/dialog.js +43 -40
- package/dist/components/ui/dropdown.js +121 -116
- package/dist/components/ui/icons.js +8 -5
- package/dist/components/ui/index.js +27 -19
- package/dist/components/ui/input.js +31 -28
- package/dist/components/ui/loader.js +9 -6
- package/dist/components/ui/primitives/button.js +33 -29
- package/dist/components/ui/primitives/input.js +44 -40
- package/dist/components/ui/primitives/modal.js +45 -41
- package/dist/components/ui/primitives/text.js +35 -29
- package/dist/components/ui/resizeable.js +54 -43
- package/dist/components/ui/text.js +50 -48
- package/dist/components/ui/textarea.js +13 -11
- package/dist/components/ui/toast.js +26 -23
- package/dist/components/ui/view.js +41 -39
- package/dist/hooks/index.js +12 -8
- package/dist/hooks/useAvatars.js +11 -8
- package/dist/hooks/useCameraToggle.js +7 -4
- package/dist/hooks/useKeyboard.js +13 -10
- package/dist/hooks/useKeyboardSlide.js +8 -5
- package/dist/hooks/useLivestreamInfo.js +17 -14
- package/dist/hooks/useOuterAndInnerDimensions.js +9 -6
- package/dist/hooks/usePlayerDimensions.js +9 -6
- package/dist/hooks/useSegmentDimensions.js +17 -0
- package/dist/hooks/useSegmentTiming.js +13 -10
- package/dist/index.js +24 -15
- package/dist/lib/facet.js +5 -1
- package/dist/lib/theme/atoms.js +153 -148
- package/dist/lib/theme/atoms.types.js +2 -1
- package/dist/lib/theme/index.js +31 -5
- package/dist/lib/theme/theme.js +91 -83
- package/dist/lib/theme/tokens.js +15 -12
- package/dist/lib/utils.js +22 -11
- package/dist/livestream-provider/index.js +19 -14
- package/dist/livestream-provider/websocket.js +14 -10
- package/dist/livestream-store/chat.js +26 -19
- package/dist/livestream-store/context.js +5 -2
- package/dist/livestream-store/index.js +7 -4
- package/dist/livestream-store/livestream-state.js +2 -1
- package/dist/livestream-store/livestream-store.js +31 -18
- package/dist/livestream-store/stream-key.js +22 -18
- package/dist/livestream-store/websocket-consumer.js +18 -14
- package/dist/player-store/context.js +5 -2
- package/dist/player-store/index.js +8 -5
- package/dist/player-store/player-provider.js +20 -15
- package/dist/player-store/player-state.js +9 -6
- package/dist/player-store/player-store.js +32 -21
- package/dist/player-store/single-player-provider.js +35 -23
- package/dist/streamplace-provider/context.js +5 -2
- package/dist/streamplace-provider/index.js +14 -10
- package/dist/streamplace-provider/poller.js +20 -17
- package/dist/streamplace-store/block.js +6 -3
- package/dist/streamplace-store/index.js +6 -3
- package/dist/streamplace-store/stream.js +14 -10
- package/dist/streamplace-store/streamplace-store.js +23 -13
- package/dist/streamplace-store/user.js +19 -14
- package/dist/streamplace-store/xrpc.js +10 -7
- package/node-compile-cache/v22.15.0-x64-92db9086-0/37be0eec +0 -0
- package/node-compile-cache/v22.15.0-x64-92db9086-0/56540125 +0 -0
- package/node-compile-cache/{v22.15.0-x64-efe9a9df-0 → v22.15.0-x64-92db9086-0}/67b1eb60 +0 -0
- package/node-compile-cache/{v22.15.0-x64-efe9a9df-0 → v22.15.0-x64-92db9086-0}/7c275f90 +0 -0
- package/package.json +6 -7
- package/src/components/mobile-player/ui/index.ts +1 -0
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +5 -4
- package/src/components/mobile-player/ui/viewers.tsx +32 -0
- package/src/components/mobile-player/video.native.tsx +50 -5
- package/src/components/ui/resizeable.tsx +15 -3
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useSegmentDimensions.tsx +18 -0
- package/tsconfig.json +2 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/56540125 +0 -0
|
@@ -1,58 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = VideoNative;
|
|
4
|
+
exports.NativeVideo = NativeVideo;
|
|
5
|
+
exports.NativeWHEP = NativeWHEP;
|
|
6
|
+
exports.NativeIngestPlayer = NativeIngestPlayer;
|
|
7
|
+
const tslib_1 = require("tslib");
|
|
8
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
9
|
+
const expo_video_1 = require("expo-video");
|
|
10
|
+
const lucide_react_native_1 = require("lucide-react-native");
|
|
11
|
+
const react_1 = require("react");
|
|
12
|
+
const react_native_1 = require("react-native");
|
|
13
|
+
const react_native_webrtc_1 = require("react-native-webrtc");
|
|
14
|
+
const __1 = require("../..");
|
|
15
|
+
const atoms_1 = require("../../lib/theme/atoms");
|
|
16
|
+
const shared_1 = require("./shared");
|
|
17
|
+
const use_webrtc_1 = tslib_1.__importStar(require("./use-webrtc"));
|
|
18
|
+
const webrtc_primitives_native_1 = require("./webrtc-primitives.native");
|
|
10
19
|
// Add NativeIngestPlayer to the switch below!
|
|
11
|
-
|
|
12
|
-
const protocol = usePlayerStore((x) => x.protocol);
|
|
13
|
-
const ingest = usePlayerStore((x) => x.ingestConnectionState) != null;
|
|
14
|
-
return (
|
|
20
|
+
function VideoNative() {
|
|
21
|
+
const protocol = (0, __1.usePlayerStore)((x) => x.protocol);
|
|
22
|
+
const ingest = (0, __1.usePlayerStore)((x) => x.ingestConnectionState) != null;
|
|
23
|
+
return ((0, jsx_runtime_1.jsx)(__1.View, { children: ingest ? ((0, jsx_runtime_1.jsx)(NativeIngestPlayer, {})) : protocol === __1.PlayerProtocol.WEBRTC ? ((0, jsx_runtime_1.jsx)(NativeWHEP, {})) : ((0, jsx_runtime_1.jsx)(NativeVideo, {})) }));
|
|
15
24
|
}
|
|
16
|
-
|
|
17
|
-
const videoRef = useRef(null);
|
|
18
|
-
const protocol = usePlayerStore((x) => x.protocol);
|
|
19
|
-
const selectedRendition = usePlayerStore((x) => x.selectedRendition);
|
|
20
|
-
const src = usePlayerStore((x) => x.src);
|
|
21
|
-
const { url } = srcToUrl({ src: src, selectedRendition }, protocol);
|
|
22
|
-
const setStatus = usePlayerStore((x) => x.setStatus);
|
|
23
|
-
const muted = usePlayerStore((x) => x.muted);
|
|
24
|
-
const volume = usePlayerStore((x) => x.volume);
|
|
25
|
-
const setFullscreen = usePlayerStore((x) => x.setFullscreen);
|
|
26
|
-
const fullscreen = usePlayerStore((x) => x.fullscreen);
|
|
27
|
-
const playerEvent = usePlayerStore((x) => x.playerEvent);
|
|
28
|
-
const spurl = useStreamplaceStore((x) => x.url);
|
|
29
|
-
const setPlayerWidth = usePlayerStore((x) => x.setPlayerWidth);
|
|
30
|
-
const setPlayerHeight = usePlayerStore((x) => x.setPlayerHeight);
|
|
25
|
+
function NativeVideo() {
|
|
26
|
+
const videoRef = (0, react_1.useRef)(null);
|
|
27
|
+
const protocol = (0, __1.usePlayerStore)((x) => x.protocol);
|
|
28
|
+
const selectedRendition = (0, __1.usePlayerStore)((x) => x.selectedRendition);
|
|
29
|
+
const src = (0, __1.usePlayerStore)((x) => x.src);
|
|
30
|
+
const { url } = (0, shared_1.srcToUrl)({ src: src, selectedRendition }, protocol);
|
|
31
|
+
const setStatus = (0, __1.usePlayerStore)((x) => x.setStatus);
|
|
32
|
+
const muted = (0, __1.usePlayerStore)((x) => x.muted);
|
|
33
|
+
const volume = (0, __1.usePlayerStore)((x) => x.volume);
|
|
34
|
+
const setFullscreen = (0, __1.usePlayerStore)((x) => x.setFullscreen);
|
|
35
|
+
const fullscreen = (0, __1.usePlayerStore)((x) => x.fullscreen);
|
|
36
|
+
const playerEvent = (0, __1.usePlayerStore)((x) => x.playerEvent);
|
|
37
|
+
const spurl = (0, __1.useStreamplaceStore)((x) => x.url);
|
|
38
|
+
const setPlayerWidth = (0, __1.usePlayerStore)((x) => x.setPlayerWidth);
|
|
39
|
+
const setPlayerHeight = (0, __1.usePlayerStore)((x) => x.setPlayerHeight);
|
|
31
40
|
// State for live dimensions
|
|
32
|
-
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
|
|
33
|
-
const handleLayout = useCallback((event) => {
|
|
41
|
+
const [dimensions, setDimensions] = (0, react_1.useState)({ width: 0, height: 0 });
|
|
42
|
+
const handleLayout = (0, react_1.useCallback)((event) => {
|
|
34
43
|
const { width, height } = event.nativeEvent.layout;
|
|
35
44
|
setDimensions({ width, height });
|
|
36
45
|
setPlayerWidth(width);
|
|
37
46
|
setPlayerHeight(height);
|
|
38
47
|
}, []);
|
|
39
|
-
useEffect(() => {
|
|
48
|
+
(0, react_1.useEffect)(() => {
|
|
40
49
|
return () => {
|
|
41
|
-
setStatus(PlayerStatus.START);
|
|
50
|
+
setStatus(__1.PlayerStatus.START);
|
|
42
51
|
};
|
|
43
52
|
}, [setStatus]);
|
|
44
|
-
const player = useVideoPlayer(url, (player) => {
|
|
53
|
+
const player = (0, expo_video_1.useVideoPlayer)(url, (player) => {
|
|
45
54
|
player.loop = true;
|
|
46
55
|
player.muted = muted;
|
|
47
56
|
player.play();
|
|
48
57
|
});
|
|
49
|
-
useEffect(() => {
|
|
58
|
+
(0, react_1.useEffect)(() => {
|
|
50
59
|
player.muted = muted;
|
|
51
60
|
}, [muted, player]);
|
|
52
|
-
useEffect(() => {
|
|
61
|
+
(0, react_1.useEffect)(() => {
|
|
53
62
|
player.volume = volume;
|
|
54
63
|
}, [volume, player]);
|
|
55
|
-
useEffect(() => {
|
|
64
|
+
(0, react_1.useEffect)(() => {
|
|
56
65
|
const subs = [
|
|
57
66
|
"playToEnd",
|
|
58
67
|
"playbackRateChange",
|
|
@@ -68,10 +77,10 @@ export function NativeVideo() {
|
|
|
68
77
|
});
|
|
69
78
|
subs.push(player.addListener("playingChange", (newIsPlaying) => {
|
|
70
79
|
if (newIsPlaying) {
|
|
71
|
-
setStatus(PlayerStatus.PLAYING);
|
|
80
|
+
setStatus(__1.PlayerStatus.PLAYING);
|
|
72
81
|
}
|
|
73
82
|
else {
|
|
74
|
-
setStatus(PlayerStatus.WAITING);
|
|
83
|
+
setStatus(__1.PlayerStatus.WAITING);
|
|
75
84
|
}
|
|
76
85
|
}));
|
|
77
86
|
return () => {
|
|
@@ -80,49 +89,49 @@ export function NativeVideo() {
|
|
|
80
89
|
}
|
|
81
90
|
};
|
|
82
91
|
}, [player, playerEvent, setStatus, spurl]);
|
|
83
|
-
return (
|
|
92
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(expo_video_1.VideoView, { ref: videoRef, player: player, allowsFullscreen: true, nativeControls: fullscreen, onFullscreenEnter: () => {
|
|
84
93
|
setFullscreen(true);
|
|
85
94
|
}, onFullscreenExit: () => {
|
|
86
95
|
setFullscreen(false);
|
|
87
96
|
}, allowsPictureInPicture: true, onLayout: handleLayout }) }));
|
|
88
97
|
}
|
|
89
|
-
|
|
90
|
-
const selectedRendition = usePlayerStore((x) => x.selectedRendition);
|
|
91
|
-
const src = usePlayerStore((x) => x.src);
|
|
92
|
-
const { url } = srcToUrl({ src: src, selectedRendition }, PlayerProtocol.WEBRTC);
|
|
93
|
-
const [stream, stuck] =
|
|
94
|
-
const setPlayerWidth = usePlayerStore((x) => x.setPlayerWidth);
|
|
95
|
-
const setPlayerHeight = usePlayerStore((x) => x.setPlayerHeight);
|
|
98
|
+
function NativeWHEP() {
|
|
99
|
+
const selectedRendition = (0, __1.usePlayerStore)((x) => x.selectedRendition);
|
|
100
|
+
const src = (0, __1.usePlayerStore)((x) => x.src);
|
|
101
|
+
const { url } = (0, shared_1.srcToUrl)({ src: src, selectedRendition }, __1.PlayerProtocol.WEBRTC);
|
|
102
|
+
const [stream, stuck] = (0, use_webrtc_1.default)(url);
|
|
103
|
+
const setPlayerWidth = (0, __1.usePlayerStore)((x) => x.setPlayerWidth);
|
|
104
|
+
const setPlayerHeight = (0, __1.usePlayerStore)((x) => x.setPlayerHeight);
|
|
96
105
|
// PiP support: wire up videoRef (no direct ref for RTCView)
|
|
97
|
-
const setVideoRef = usePlayerStore((x) => x.setVideoRef);
|
|
106
|
+
const setVideoRef = (0, __1.usePlayerStore)((x) => x.setVideoRef);
|
|
98
107
|
// State for live dimensions
|
|
99
|
-
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
|
|
100
|
-
const handleLayout = useCallback((event) => {
|
|
108
|
+
const [dimensions, setDimensions] = (0, react_1.useState)({ width: 0, height: 0 });
|
|
109
|
+
const handleLayout = (0, react_1.useCallback)((event) => {
|
|
101
110
|
const { width, height } = event.nativeEvent.layout;
|
|
102
111
|
setDimensions({ width, height });
|
|
103
112
|
setPlayerWidth(width);
|
|
104
113
|
setPlayerHeight(height);
|
|
105
114
|
}, []);
|
|
106
|
-
const setStatus = usePlayerStore((x) => x.setStatus);
|
|
107
|
-
const muted = usePlayerStore((x) => x.muted);
|
|
108
|
-
const volume = usePlayerStore((x) => x.volume);
|
|
109
|
-
useEffect(() => {
|
|
115
|
+
const setStatus = (0, __1.usePlayerStore)((x) => x.setStatus);
|
|
116
|
+
const muted = (0, __1.usePlayerStore)((x) => x.muted);
|
|
117
|
+
const volume = (0, __1.usePlayerStore)((x) => x.volume);
|
|
118
|
+
(0, react_1.useEffect)(() => {
|
|
110
119
|
if (stuck) {
|
|
111
|
-
setStatus(PlayerStatus.STALLED);
|
|
120
|
+
setStatus(__1.PlayerStatus.STALLED);
|
|
112
121
|
}
|
|
113
122
|
else {
|
|
114
|
-
setStatus(PlayerStatus.PLAYING);
|
|
123
|
+
setStatus(__1.PlayerStatus.PLAYING);
|
|
115
124
|
}
|
|
116
125
|
}, [stuck, setStatus]);
|
|
117
126
|
const mediaStream = stream;
|
|
118
|
-
useEffect(() => {
|
|
127
|
+
(0, react_1.useEffect)(() => {
|
|
119
128
|
if (!mediaStream) {
|
|
120
|
-
setStatus(PlayerStatus.WAITING);
|
|
129
|
+
setStatus(__1.PlayerStatus.WAITING);
|
|
121
130
|
return;
|
|
122
131
|
}
|
|
123
|
-
setStatus(PlayerStatus.PLAYING);
|
|
132
|
+
setStatus(__1.PlayerStatus.PLAYING);
|
|
124
133
|
}, [mediaStream, setStatus]);
|
|
125
|
-
useEffect(() => {
|
|
134
|
+
(0, react_1.useEffect)(() => {
|
|
126
135
|
if (!mediaStream) {
|
|
127
136
|
return;
|
|
128
137
|
}
|
|
@@ -133,15 +142,15 @@ export function NativeWHEP() {
|
|
|
133
142
|
});
|
|
134
143
|
}, [mediaStream, muted, volume]);
|
|
135
144
|
// Keep the playerStore videoRef in sync for PiP (if possible)
|
|
136
|
-
useEffect(() => {
|
|
145
|
+
(0, react_1.useEffect)(() => {
|
|
137
146
|
if (typeof setVideoRef === "function") {
|
|
138
147
|
setVideoRef(null); // No direct ref for RTCView, but keep API consistent
|
|
139
148
|
}
|
|
140
149
|
}, [setVideoRef]);
|
|
141
150
|
if (!mediaStream) {
|
|
142
|
-
return
|
|
151
|
+
return (0, jsx_runtime_1.jsx)(__1.View, {});
|
|
143
152
|
}
|
|
144
|
-
return (
|
|
153
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(react_native_webrtc_1.RTCView, { mirror: false, objectFit: "contain", streamURL: mediaStream.toURL(), onLayout: handleLayout, pictureInPictureEnabled: true, autoStartPictureInPicture: true, pictureInPicturePreferredSize: {
|
|
145
154
|
width: 160,
|
|
146
155
|
height: 90,
|
|
147
156
|
}, style: {
|
|
@@ -150,32 +159,32 @@ export function NativeWHEP() {
|
|
|
150
159
|
flex: 1,
|
|
151
160
|
} }) }));
|
|
152
161
|
}
|
|
153
|
-
|
|
154
|
-
const ingestStarting =
|
|
155
|
-
const ingestMediaSource =
|
|
156
|
-
const ingestAutoStart =
|
|
157
|
-
const setStatus =
|
|
158
|
-
const setVideoRef = usePlayerStore((x) => x.setVideoRef);
|
|
159
|
-
const [error, setError] = useState(null);
|
|
160
|
-
const ingestCamera =
|
|
161
|
-
useEffect(() => {
|
|
162
|
-
setStatus(
|
|
162
|
+
function NativeIngestPlayer() {
|
|
163
|
+
const ingestStarting = (0, __1.usePlayerStore)((x) => x.ingestStarting);
|
|
164
|
+
const ingestMediaSource = (0, __1.usePlayerStore)((x) => x.ingestMediaSource);
|
|
165
|
+
const ingestAutoStart = (0, __1.usePlayerStore)((x) => x.ingestAutoStart);
|
|
166
|
+
const setStatus = (0, __1.usePlayerStore)((x) => x.setStatus);
|
|
167
|
+
const setVideoRef = (0, __1.usePlayerStore)((x) => x.setVideoRef);
|
|
168
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
169
|
+
const ingestCamera = (0, __1.usePlayerStore)((x) => x.ingestCamera);
|
|
170
|
+
(0, react_1.useEffect)(() => {
|
|
171
|
+
setStatus(__1.PlayerStatus.PLAYING);
|
|
163
172
|
}, [setStatus]);
|
|
164
|
-
useEffect(() => {
|
|
173
|
+
(0, react_1.useEffect)(() => {
|
|
165
174
|
if (typeof setVideoRef === "function") {
|
|
166
175
|
setVideoRef(null);
|
|
167
176
|
}
|
|
168
177
|
}, [setVideoRef]);
|
|
169
|
-
const url = useStreamplaceStore((x) => x.url);
|
|
170
|
-
const [lms, setLocalMediaStream] = useState(null);
|
|
171
|
-
const [, setRemoteMediaStream] = useWebRTCIngest({
|
|
178
|
+
const url = (0, __1.useStreamplaceStore)((x) => x.url);
|
|
179
|
+
const [lms, setLocalMediaStream] = (0, react_1.useState)(null);
|
|
180
|
+
const [, setRemoteMediaStream] = (0, use_webrtc_1.useWebRTCIngest)({
|
|
172
181
|
endpoint: `${url}/api/ingest/webrtc`,
|
|
173
182
|
});
|
|
174
183
|
// Use lms directly as localMediaStream
|
|
175
184
|
const localMediaStream = lms;
|
|
176
|
-
useEffect(() => {
|
|
177
|
-
if (ingestMediaSource === IngestMediaSource.DISPLAY) {
|
|
178
|
-
mediaDevices
|
|
185
|
+
(0, react_1.useEffect)(() => {
|
|
186
|
+
if (ingestMediaSource === __1.IngestMediaSource.DISPLAY) {
|
|
187
|
+
webrtc_primitives_native_1.mediaDevices
|
|
179
188
|
.getDisplayMedia()
|
|
180
189
|
.then((stream) => {
|
|
181
190
|
console.log("display media", stream);
|
|
@@ -187,7 +196,7 @@ export function NativeIngestPlayer() {
|
|
|
187
196
|
});
|
|
188
197
|
}
|
|
189
198
|
else {
|
|
190
|
-
mediaDevices
|
|
199
|
+
webrtc_primitives_native_1.mediaDevices
|
|
191
200
|
.getUserMedia({
|
|
192
201
|
audio: {
|
|
193
202
|
// deviceId: "audio-1",
|
|
@@ -205,14 +214,29 @@ export function NativeIngestPlayer() {
|
|
|
205
214
|
})
|
|
206
215
|
.then((stream) => {
|
|
207
216
|
setLocalMediaStream(stream);
|
|
217
|
+
let errs = [];
|
|
218
|
+
if (stream.getAudioTracks().length === 0) {
|
|
219
|
+
console.warn("No audio tracks found in user media stream");
|
|
220
|
+
errs.push("microphone");
|
|
221
|
+
}
|
|
222
|
+
if (stream.getVideoTracks().length === 0) {
|
|
223
|
+
console.warn("No video tracks found in user media stream");
|
|
224
|
+
errs.push("camera");
|
|
225
|
+
}
|
|
226
|
+
if (errs.length > 0) {
|
|
227
|
+
setError(new Error(`We could not access your ${errs.join(" and ")}. To stream, you need to give us permission to access these.`));
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
setError(null);
|
|
231
|
+
}
|
|
208
232
|
})
|
|
209
233
|
.catch((e) => {
|
|
210
234
|
console.error("error getting user media", e);
|
|
211
|
-
setError(new Error("We could not access your camera or microphone.
|
|
235
|
+
setError(new Error("We could not access your camera or microphone. To stream, you need to give us permission to access these."));
|
|
212
236
|
});
|
|
213
237
|
}
|
|
214
238
|
}, [ingestMediaSource, ingestCamera]);
|
|
215
|
-
useEffect(() => {
|
|
239
|
+
(0, react_1.useEffect)(() => {
|
|
216
240
|
if (!ingestStarting && !ingestAutoStart) {
|
|
217
241
|
setRemoteMediaStream(null);
|
|
218
242
|
return;
|
|
@@ -228,9 +252,9 @@ export function NativeIngestPlayer() {
|
|
|
228
252
|
return null;
|
|
229
253
|
}
|
|
230
254
|
if (error) {
|
|
231
|
-
return (
|
|
255
|
+
return ((0, jsx_runtime_1.jsxs)(__1.View, { backgroundColor: atoms_1.colors.destructive[900], style: [atoms_1.p[4], atoms_1.m[4], atoms_1.gap.all[2], { borderRadius: atoms_1.borderRadius.md }], children: [(0, jsx_runtime_1.jsx)(__1.View, { children: (0, jsx_runtime_1.jsx)(__1.Text, { style: [atoms_1.fontWeight.semibold], size: "2xl", children: "Error encountered!" }) }), (0, jsx_runtime_1.jsx)(__1.Text, { children: error.message }), error.message.includes("To stream, you need to give us permission to access these.") && ((0, jsx_runtime_1.jsx)(__1.Button, { onPress: react_native_1.Linking.openSettings, style: [atoms_1.h[10]], variant: "secondary", children: (0, jsx_runtime_1.jsxs)(__1.View, { style: [atoms_1.layout.flex.row, atoms_1.gap.all[1]], children: [(0, jsx_runtime_1.jsx)(__1.Text, { children: "Open Settings" }), " ", (0, jsx_runtime_1.jsx)(lucide_react_native_1.ArrowRight, { color: "white", size: "18" })] }) }))] }));
|
|
232
256
|
}
|
|
233
|
-
return (
|
|
257
|
+
return ((0, jsx_runtime_1.jsx)(react_native_webrtc_1.RTCView, { mirror: ingestCamera !== "environment", objectFit: "contain", streamURL: localMediaStream.toURL(), zOrder: 0, style: {
|
|
234
258
|
minWidth: "100%",
|
|
235
259
|
minHeight: "100%",
|
|
236
260
|
flex: 1,
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useWebRTCDiagnostics = useWebRTCDiagnostics;
|
|
4
|
+
exports.logWebRTCDiagnostics = logWebRTCDiagnostics;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
function useWebRTCDiagnostics() {
|
|
7
|
+
const [diagnostics, setDiagnostics] = (0, react_1.useState)({
|
|
4
8
|
done: false,
|
|
5
9
|
browserSupport: false,
|
|
6
10
|
rtcPeerConnection: false,
|
|
@@ -10,7 +14,7 @@ export function useWebRTCDiagnostics() {
|
|
|
10
14
|
errors: [],
|
|
11
15
|
warnings: [],
|
|
12
16
|
});
|
|
13
|
-
useEffect(() => {
|
|
17
|
+
(0, react_1.useEffect)(() => {
|
|
14
18
|
const errors = [];
|
|
15
19
|
const warnings = [];
|
|
16
20
|
// Check if we're in a browser environment
|
|
@@ -80,7 +84,7 @@ export function useWebRTCDiagnostics() {
|
|
|
80
84
|
}, []);
|
|
81
85
|
return diagnostics;
|
|
82
86
|
}
|
|
83
|
-
|
|
87
|
+
function logWebRTCDiagnostics() {
|
|
84
88
|
console.group("WebRTC Diagnostics");
|
|
85
89
|
// Log browser support
|
|
86
90
|
console.log("RTCPeerConnection:", !!window.RTCPeerConnection);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkWebRTCSupport = exports.mediaDevices = exports.WebRTCMediaStream = exports.RTCSessionDescription = exports.RTCPeerConnection = void 0;
|
|
1
4
|
// Browser compatibility checks for WebRTC
|
|
2
5
|
const checkWebRTCSupport = () => {
|
|
3
6
|
if (typeof window === "undefined") {
|
|
@@ -10,6 +13,7 @@ const checkWebRTCSupport = () => {
|
|
|
10
13
|
throw new Error("RTCSessionDescription is not supported in this browser. Please use a modern browser that supports WebRTC.");
|
|
11
14
|
}
|
|
12
15
|
};
|
|
16
|
+
exports.checkWebRTCSupport = checkWebRTCSupport;
|
|
13
17
|
// Check support immediately
|
|
14
18
|
try {
|
|
15
19
|
checkWebRTCSupport();
|
|
@@ -17,9 +21,7 @@ try {
|
|
|
17
21
|
catch (error) {
|
|
18
22
|
console.error("WebRTC Compatibility Error:", error.message);
|
|
19
23
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// Export the compatibility checker for use in other components
|
|
25
|
-
export { checkWebRTCSupport };
|
|
24
|
+
exports.RTCPeerConnection = window.RTCPeerConnection;
|
|
25
|
+
exports.RTCSessionDescription = window.RTCSessionDescription;
|
|
26
|
+
exports.WebRTCMediaStream = window.MediaStream;
|
|
27
|
+
exports.mediaDevices = navigator.mediaDevices;
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mediaDevices = exports.WebRTCMediaStream = exports.RTCSessionDescription = exports.RTCPeerConnection = void 0;
|
|
4
|
+
var react_native_webrtc_1 = require("react-native-webrtc");
|
|
5
|
+
Object.defineProperty(exports, "RTCPeerConnection", { enumerable: true, get: function () { return react_native_webrtc_1.RTCPeerConnection; } });
|
|
6
|
+
Object.defineProperty(exports, "RTCSessionDescription", { enumerable: true, get: function () { return react_native_webrtc_1.RTCSessionDescription; } });
|
|
7
|
+
Object.defineProperty(exports, "WebRTCMediaStream", { enumerable: true, get: function () { return react_native_webrtc_1.MediaStream; } });
|
|
8
|
+
Object.defineProperty(exports, "mediaDevices", { enumerable: true, get: function () { return react_native_webrtc_1.mediaDevices; } });
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buttonVariants = exports.Button = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const class_variance_authority_1 = require("class-variance-authority");
|
|
7
|
+
const react_1 = tslib_1.__importStar(require("react"));
|
|
8
|
+
const react_native_1 = require("react-native");
|
|
9
|
+
const theme_1 = require("../../lib/theme/theme");
|
|
10
|
+
const tokens = tslib_1.__importStar(require("../../lib/theme/tokens"));
|
|
11
|
+
const button_1 = require("./primitives/button");
|
|
12
|
+
const text_1 = require("./primitives/text");
|
|
9
13
|
// Button variants using class-variance-authority pattern
|
|
10
|
-
const buttonVariants = cva("", {
|
|
14
|
+
const buttonVariants = (0, class_variance_authority_1.cva)("", {
|
|
11
15
|
variants: {
|
|
12
16
|
variant: {
|
|
13
17
|
primary: "primary",
|
|
@@ -30,27 +34,28 @@ const buttonVariants = cva("", {
|
|
|
30
34
|
size: "md",
|
|
31
35
|
},
|
|
32
36
|
});
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
exports.buttonVariants = buttonVariants;
|
|
38
|
+
exports.Button = (0, react_1.forwardRef)(({ variant = "primary", size = "md", children, leftIcon, rightIcon, loading = false, loadingText, disabled, style, ...props }, ref) => {
|
|
39
|
+
const { theme } = (0, theme_1.useTheme)();
|
|
35
40
|
// Create dynamic styles based on theme
|
|
36
|
-
const styles = useMemo(() => createStyles(theme), [theme]);
|
|
41
|
+
const styles = (0, react_1.useMemo)(() => createStyles(theme), [theme]);
|
|
37
42
|
// Get variant styles
|
|
38
|
-
const buttonStyle = useMemo(() => {
|
|
43
|
+
const buttonStyle = (0, react_1.useMemo)(() => {
|
|
39
44
|
const variantStyle = styles[`${variant}Button`];
|
|
40
45
|
const sizeStyle = styles[`${size}Button`];
|
|
41
46
|
return [variantStyle, sizeStyle];
|
|
42
47
|
}, [variant, size, styles]);
|
|
43
48
|
// Get inner styles for button content
|
|
44
|
-
const buttonInnerStyle = useMemo(() => {
|
|
49
|
+
const buttonInnerStyle = (0, react_1.useMemo)(() => {
|
|
45
50
|
const sizeInnerStyle = styles[`${size}ButtonInner`];
|
|
46
51
|
return sizeInnerStyle;
|
|
47
52
|
}, [size, styles]);
|
|
48
|
-
const textStyle =
|
|
53
|
+
const textStyle = react_1.default.useMemo(() => {
|
|
49
54
|
const variantTextStyle = styles[`${variant}Text`];
|
|
50
55
|
const sizeTextStyle = styles[`${size}Text`];
|
|
51
56
|
return [variantTextStyle, sizeTextStyle];
|
|
52
57
|
}, [variant, size, styles]);
|
|
53
|
-
const iconSize =
|
|
58
|
+
const iconSize = react_1.default.useMemo(() => {
|
|
54
59
|
switch (size) {
|
|
55
60
|
case "sm":
|
|
56
61
|
return 16;
|
|
@@ -63,7 +68,7 @@ export const Button = forwardRef(({ variant = "primary", size = "md", children,
|
|
|
63
68
|
return 18;
|
|
64
69
|
}
|
|
65
70
|
}, [size]);
|
|
66
|
-
const spinnerSize = useMemo(() => {
|
|
71
|
+
const spinnerSize = (0, react_1.useMemo)(() => {
|
|
67
72
|
switch (size) {
|
|
68
73
|
case "sm":
|
|
69
74
|
return "small";
|
|
@@ -75,7 +80,7 @@ export const Button = forwardRef(({ variant = "primary", size = "md", children,
|
|
|
75
80
|
return "small";
|
|
76
81
|
}
|
|
77
82
|
}, [size]);
|
|
78
|
-
const spinnerColor = useMemo(() => {
|
|
83
|
+
const spinnerColor = (0, react_1.useMemo)(() => {
|
|
79
84
|
switch (variant) {
|
|
80
85
|
case "outline":
|
|
81
86
|
case "ghost":
|
|
@@ -88,12 +93,12 @@ export const Button = forwardRef(({ variant = "primary", size = "md", children,
|
|
|
88
93
|
return theme.colors.primaryForeground;
|
|
89
94
|
}
|
|
90
95
|
}, [variant, theme.colors]);
|
|
91
|
-
return (
|
|
96
|
+
return ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Root, { ref: ref, disabled: disabled || loading, style: [buttonStyle, style], ...props, children: (0, jsx_runtime_1.jsxs)(button_1.ButtonPrimitive.Content, { style: buttonInnerStyle, children: [loading && !leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", style: { width: iconSize, height: iconSize }, children: leftIcon })) : null, (0, jsx_runtime_1.jsx)(text_1.TextPrimitive.Root, { style: textStyle, children: loading && loadingText ? loadingText : children }), loading && rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", style: { width: iconSize, height: iconSize }, children: rightIcon })) : null] }) }));
|
|
92
97
|
});
|
|
93
|
-
Button.displayName = "Button";
|
|
98
|
+
exports.Button.displayName = "Button";
|
|
94
99
|
// Create theme-based styles
|
|
95
100
|
function createStyles(theme) {
|
|
96
|
-
return StyleSheet.create({
|
|
101
|
+
return react_native_1.StyleSheet.create({
|
|
97
102
|
// Variant styles
|
|
98
103
|
primaryButton: {
|
|
99
104
|
backgroundColor: theme.colors.primary,
|
|
@@ -216,5 +221,3 @@ function createStyles(theme) {
|
|
|
216
221
|
},
|
|
217
222
|
});
|
|
218
223
|
}
|
|
219
|
-
// Export button variants for external use
|
|
220
|
-
export { buttonVariants };
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dialogVariants = exports.DialogFooter = exports.DialogDescription = exports.DialogTitle = exports.Dialog = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const class_variance_authority_1 = require("class-variance-authority");
|
|
7
|
+
const lucide_react_native_1 = require("lucide-react-native");
|
|
8
|
+
const react_1 = tslib_1.__importStar(require("react"));
|
|
9
|
+
const react_native_1 = require("react-native");
|
|
10
|
+
const theme_1 = require("../../lib/theme/theme");
|
|
11
|
+
const icons_1 = require("./icons");
|
|
12
|
+
const modal_1 = require("./primitives/modal");
|
|
13
|
+
const ThemedX = (0, icons_1.createThemedIcon)(lucide_react_native_1.X);
|
|
10
14
|
// Dialog variants using class-variance-authority pattern
|
|
11
|
-
const dialogVariants = cva("", {
|
|
15
|
+
const dialogVariants = (0, class_variance_authority_1.cva)("", {
|
|
12
16
|
variants: {
|
|
13
17
|
variant: {
|
|
14
18
|
default: "default",
|
|
@@ -36,11 +40,12 @@ const dialogVariants = cva("", {
|
|
|
36
40
|
position: "center",
|
|
37
41
|
},
|
|
38
42
|
});
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
exports.dialogVariants = dialogVariants;
|
|
44
|
+
exports.Dialog = (0, react_1.forwardRef)(({ variant = "left", size = "md", position = "center", children, title, description, dismissible = true, showCloseButton = true, onClose, open = false, onOpenChange, ...props }, ref) => {
|
|
45
|
+
const { theme } = (0, theme_1.useTheme)();
|
|
41
46
|
// Create dynamic styles based on theme
|
|
42
|
-
const styles =
|
|
43
|
-
const handleClose =
|
|
47
|
+
const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
|
|
48
|
+
const handleClose = react_1.default.useCallback(() => {
|
|
44
49
|
if (onClose) {
|
|
45
50
|
onClose();
|
|
46
51
|
}
|
|
@@ -48,61 +53,61 @@ export const Dialog = forwardRef(({ variant = "left", size = "md", position = "c
|
|
|
48
53
|
onOpenChange(false);
|
|
49
54
|
}
|
|
50
55
|
}, [onClose, onOpenChange]);
|
|
51
|
-
const presentationStyle =
|
|
52
|
-
if (variant === "sheet" && Platform.OS === "ios") {
|
|
56
|
+
const presentationStyle = react_1.default.useMemo(() => {
|
|
57
|
+
if (variant === "sheet" && react_native_1.Platform.OS === "ios") {
|
|
53
58
|
return "pageSheet";
|
|
54
59
|
}
|
|
55
60
|
if (variant === "fullscreen") {
|
|
56
61
|
return "fullScreen";
|
|
57
62
|
}
|
|
58
|
-
return Platform.OS === "ios"
|
|
63
|
+
return react_native_1.Platform.OS === "ios"
|
|
59
64
|
? "pageSheet"
|
|
60
65
|
: "fullScreen";
|
|
61
66
|
}, [variant]);
|
|
62
|
-
const animationType =
|
|
67
|
+
const animationType = react_1.default.useMemo(() => {
|
|
63
68
|
if (variant === "sheet") {
|
|
64
69
|
return "slide";
|
|
65
70
|
}
|
|
66
71
|
return "fade";
|
|
67
72
|
}, [variant]);
|
|
68
|
-
return (
|
|
73
|
+
return ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Root, { ref: ref, open: open, onOpenChange: onOpenChange, presentationStyle: presentationStyle, animationType: animationType, ...props, children: (0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Overlay, { dismissible: dismissible, onDismiss: handleClose, style: styles.overlay, children: (0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Content, { position: position || "left", size: size || "md", style: [
|
|
69
74
|
styles.content,
|
|
70
75
|
styles[`${variant}Content`],
|
|
71
76
|
styles[`${size}Content`],
|
|
72
|
-
], children: [(title || showCloseButton) && (
|
|
77
|
+
], children: [(title || showCloseButton) && ((0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Header, { withBorder: variant !== "sheet", style: styles.header, children: [(0, jsx_runtime_1.jsx)(exports.DialogTitle, { children: title }), showCloseButton && ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Close, { onClose: handleClose, style: styles.closeButton, children: (0, jsx_runtime_1.jsx)(DialogCloseIcon, {}) }))] })), (0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Body, { scrollable: variant !== "fullscreen", style: styles.body, children: [description && ((0, jsx_runtime_1.jsx)(exports.DialogDescription, { children: description })), children] })] }) }) }));
|
|
73
78
|
});
|
|
74
|
-
Dialog.displayName = "Dialog";
|
|
75
|
-
|
|
76
|
-
const { theme } = useTheme();
|
|
77
|
-
const styles =
|
|
79
|
+
exports.Dialog.displayName = "Dialog";
|
|
80
|
+
exports.DialogTitle = (0, react_1.forwardRef)(({ children, style, ...props }, ref) => {
|
|
81
|
+
const { theme } = (0, theme_1.useTheme)();
|
|
82
|
+
const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
|
|
78
83
|
if (!children)
|
|
79
84
|
return null;
|
|
80
|
-
return (
|
|
85
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [styles.title, style], ...props, children: children }));
|
|
81
86
|
});
|
|
82
|
-
DialogTitle.displayName = "DialogTitle";
|
|
83
|
-
|
|
84
|
-
const { theme } = useTheme();
|
|
85
|
-
const styles =
|
|
87
|
+
exports.DialogTitle.displayName = "DialogTitle";
|
|
88
|
+
exports.DialogDescription = (0, react_1.forwardRef)(({ children, style, ...props }, ref) => {
|
|
89
|
+
const { theme } = (0, theme_1.useTheme)();
|
|
90
|
+
const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
|
|
86
91
|
if (!children)
|
|
87
92
|
return null;
|
|
88
|
-
return (
|
|
93
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [styles.description, style], ...props, children: children }));
|
|
89
94
|
});
|
|
90
|
-
DialogDescription.displayName = "DialogDescription";
|
|
91
|
-
|
|
92
|
-
const { theme } = useTheme();
|
|
93
|
-
const styles =
|
|
95
|
+
exports.DialogDescription.displayName = "DialogDescription";
|
|
96
|
+
exports.DialogFooter = (0, react_1.forwardRef)(({ children, direction = "row", justify = "flex-end", withBorder = true, style, ...props }, ref) => {
|
|
97
|
+
const { theme } = (0, theme_1.useTheme)();
|
|
98
|
+
const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
|
|
94
99
|
if (!children)
|
|
95
100
|
return null;
|
|
96
|
-
return (
|
|
101
|
+
return ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Footer, { ref: ref, withBorder: withBorder, direction: direction, justify: justify, style: [styles.footer, style], ...props, children: children }));
|
|
97
102
|
});
|
|
98
|
-
DialogFooter.displayName = "DialogFooter";
|
|
103
|
+
exports.DialogFooter.displayName = "DialogFooter";
|
|
99
104
|
// Dialog Close Icon component (Lucide X)
|
|
100
105
|
const DialogCloseIcon = () => {
|
|
101
|
-
return
|
|
106
|
+
return (0, jsx_runtime_1.jsx)(ThemedX, { size: "md", variant: "muted" });
|
|
102
107
|
};
|
|
103
108
|
// Create theme-aware styles
|
|
104
109
|
function createStyles(theme) {
|
|
105
|
-
return StyleSheet.create({
|
|
110
|
+
return react_native_1.StyleSheet.create({
|
|
106
111
|
overlay: {
|
|
107
112
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
108
113
|
},
|
|
@@ -199,5 +204,3 @@ function createStyles(theme) {
|
|
|
199
204
|
},
|
|
200
205
|
});
|
|
201
206
|
}
|
|
202
|
-
// Export dialog variants for external use
|
|
203
|
-
export { dialogVariants };
|