@streamplace/components 0.7.13 → 0.7.15
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/package.json +13 -16
- package/src/components/mobile-player/fullscreen.native.tsx +15 -20
- package/src/components/mobile-player/fullscreen.tsx +10 -2
- package/src/components/mobile-player/player.tsx +7 -1
- package/src/components/mobile-player/props.tsx +2 -0
- package/src/components/mobile-player/video.native.tsx +28 -11
- package/src/components/mobile-player/video.tsx +14 -3
- package/src/hooks/useLivestreamInfo.ts +6 -2
- package/src/lib/browser.ts +27 -0
- package/src/livestream-store/stream-key.tsx +1 -28
- package/src/streamplace-store/stream.tsx +51 -13
- package/dist/assets/emoji-data.json +0 -19371
- package/dist/components/chat/chat-box.js +0 -314
- package/dist/components/chat/chat-message.js +0 -87
- package/dist/components/chat/chat.js +0 -149
- package/dist/components/chat/emoji-suggestions.js +0 -35
- package/dist/components/chat/mention-suggestions.js +0 -42
- package/dist/components/chat/mod-view.js +0 -94
- package/dist/components/chat/system-message.js +0 -19
- package/dist/components/dashboard/chat-panel.js +0 -38
- package/dist/components/dashboard/header.js +0 -80
- package/dist/components/dashboard/index.js +0 -14
- package/dist/components/dashboard/information-widget.js +0 -234
- package/dist/components/dashboard/mod-actions.js +0 -71
- package/dist/components/dashboard/problems.js +0 -74
- package/dist/components/icons/bluesky-icon.js +0 -9
- package/dist/components/keep-awake.js +0 -7
- package/dist/components/keep-awake.native.js +0 -16
- package/dist/components/mobile-player/fullscreen.js +0 -74
- package/dist/components/mobile-player/fullscreen.native.js +0 -155
- package/dist/components/mobile-player/player.js +0 -94
- package/dist/components/mobile-player/props.js +0 -2
- package/dist/components/mobile-player/shared.js +0 -54
- package/dist/components/mobile-player/ui/countdown.js +0 -83
- package/dist/components/mobile-player/ui/index.js +0 -11
- package/dist/components/mobile-player/ui/input.js +0 -42
- package/dist/components/mobile-player/ui/metrics.js +0 -44
- package/dist/components/mobile-player/ui/report-modal.js +0 -90
- package/dist/components/mobile-player/ui/streamer-context-menu.js +0 -7
- package/dist/components/mobile-player/ui/streamer-loading-overlay.js +0 -104
- package/dist/components/mobile-player/ui/viewer-context-menu.js +0 -51
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js +0 -49
- package/dist/components/mobile-player/ui/viewers.js +0 -23
- package/dist/components/mobile-player/use-webrtc.js +0 -243
- package/dist/components/mobile-player/video-retry.js +0 -29
- package/dist/components/mobile-player/video.js +0 -460
- package/dist/components/mobile-player/video.native.js +0 -276
- package/dist/components/mobile-player/webrtc-diagnostics.js +0 -110
- package/dist/components/mobile-player/webrtc-primitives.js +0 -27
- package/dist/components/mobile-player/webrtc-primitives.native.js +0 -8
- package/dist/components/share/sharesheet.js +0 -91
- package/dist/components/ui/button.js +0 -223
- package/dist/components/ui/dialog.js +0 -206
- package/dist/components/ui/dropdown.js +0 -172
- package/dist/components/ui/icons.js +0 -25
- package/dist/components/ui/index.js +0 -34
- package/dist/components/ui/info-box.js +0 -31
- package/dist/components/ui/info-row.js +0 -23
- package/dist/components/ui/input.js +0 -205
- package/dist/components/ui/loader.js +0 -10
- package/dist/components/ui/primitives/button.js +0 -125
- package/dist/components/ui/primitives/input.js +0 -206
- package/dist/components/ui/primitives/modal.js +0 -206
- package/dist/components/ui/primitives/text.js +0 -292
- package/dist/components/ui/resizeable.js +0 -121
- package/dist/components/ui/slider.js +0 -5
- package/dist/components/ui/text.js +0 -177
- package/dist/components/ui/textarea.js +0 -19
- package/dist/components/ui/toast.js +0 -175
- package/dist/components/ui/view.js +0 -252
- package/dist/hooks/index.js +0 -14
- package/dist/hooks/useAvatars.js +0 -35
- package/dist/hooks/useCameraToggle.js +0 -12
- package/dist/hooks/useKeyboard.js +0 -36
- package/dist/hooks/useKeyboardSlide.js +0 -14
- package/dist/hooks/useLivestreamInfo.js +0 -65
- package/dist/hooks/useOuterAndInnerDimensions.js +0 -30
- package/dist/hooks/usePlayerDimensions.js +0 -22
- package/dist/hooks/usePointerDevice.js +0 -71
- package/dist/hooks/useSegmentDimensions.js +0 -17
- package/dist/hooks/useSegmentTiming.js +0 -65
- package/dist/index.js +0 -34
- package/dist/lib/facet.js +0 -92
- package/dist/lib/system-messages.js +0 -101
- package/dist/lib/theme/atoms.js +0 -646
- package/dist/lib/theme/atoms.types.js +0 -6
- package/dist/lib/theme/index.js +0 -35
- package/dist/lib/theme/theme.js +0 -256
- package/dist/lib/theme/tokens.js +0 -659
- package/dist/lib/utils.js +0 -105
- package/dist/livestream-provider/index.js +0 -30
- package/dist/livestream-provider/websocket.js +0 -45
- package/dist/livestream-store/chat.js +0 -286
- package/dist/livestream-store/context.js +0 -5
- package/dist/livestream-store/index.js +0 -7
- package/dist/livestream-store/livestream-state.js +0 -2
- package/dist/livestream-store/livestream-store.js +0 -58
- package/dist/livestream-store/problems.js +0 -76
- package/dist/livestream-store/stream-key.js +0 -119
- package/dist/livestream-store/websocket-consumer.js +0 -94
- package/dist/player-store/context.js +0 -5
- package/dist/player-store/index.js +0 -9
- package/dist/player-store/player-provider.js +0 -57
- package/dist/player-store/player-state.js +0 -25
- package/dist/player-store/player-store.js +0 -199
- package/dist/player-store/single-player-provider.js +0 -121
- package/dist/streamplace-provider/context.js +0 -5
- package/dist/streamplace-provider/index.js +0 -20
- package/dist/streamplace-provider/poller.js +0 -49
- package/dist/streamplace-provider/xrpc.js +0 -0
- package/dist/streamplace-store/block.js +0 -65
- package/dist/streamplace-store/index.js +0 -6
- package/dist/streamplace-store/stream.js +0 -218
- package/dist/streamplace-store/streamplace-store.js +0 -47
- package/dist/streamplace-store/user.js +0 -52
- package/dist/streamplace-store/xrpc.js +0 -15
- package/dist/ui/index.js +0 -79
- 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
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/67b1eb60 +0 -0
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/7c275f90 +0 -0
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,276 +0,0 @@
|
|
|
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");
|
|
19
|
-
// Add NativeIngestPlayer to the switch below!
|
|
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, {})) }));
|
|
24
|
-
}
|
|
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);
|
|
40
|
-
// State for live dimensions
|
|
41
|
-
const [dimensions, setDimensions] = (0, react_1.useState)({ width: 0, height: 0 });
|
|
42
|
-
const handleLayout = (0, react_1.useCallback)((event) => {
|
|
43
|
-
const { width, height } = event.nativeEvent.layout;
|
|
44
|
-
setDimensions({ width, height });
|
|
45
|
-
setPlayerWidth(width);
|
|
46
|
-
setPlayerHeight(height);
|
|
47
|
-
}, []);
|
|
48
|
-
(0, react_1.useEffect)(() => {
|
|
49
|
-
return () => {
|
|
50
|
-
setStatus(__1.PlayerStatus.START);
|
|
51
|
-
};
|
|
52
|
-
}, [setStatus]);
|
|
53
|
-
const player = (0, expo_video_1.useVideoPlayer)(url, (player) => {
|
|
54
|
-
player.addListener("playingChange", (newIsPlaying) => {
|
|
55
|
-
console.log("playingChange", newIsPlaying);
|
|
56
|
-
if (newIsPlaying) {
|
|
57
|
-
setStatus(__1.PlayerStatus.PLAYING);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
setStatus(__1.PlayerStatus.WAITING);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
player.loop = true;
|
|
64
|
-
player.muted = muted;
|
|
65
|
-
player.play();
|
|
66
|
-
});
|
|
67
|
-
(0, react_1.useEffect)(() => {
|
|
68
|
-
player.muted = muted;
|
|
69
|
-
}, [muted, player]);
|
|
70
|
-
(0, react_1.useEffect)(() => {
|
|
71
|
-
player.volume = volume;
|
|
72
|
-
}, [volume, player]);
|
|
73
|
-
(0, react_1.useEffect)(() => {
|
|
74
|
-
const subs = [
|
|
75
|
-
"playToEnd",
|
|
76
|
-
"playbackRateChange",
|
|
77
|
-
"playingChange",
|
|
78
|
-
"sourceChange",
|
|
79
|
-
"statusChange",
|
|
80
|
-
"volumeChange",
|
|
81
|
-
].map((evType) => {
|
|
82
|
-
return player.addListener(evType, (...args) => {
|
|
83
|
-
const now = new Date();
|
|
84
|
-
console.log("video native event", evType);
|
|
85
|
-
playerEvent(spurl, now.toISOString(), evType, { args: args });
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
subs.push(player.addListener("playingChange", (newIsPlaying) => {
|
|
89
|
-
console.log("playingChange", newIsPlaying);
|
|
90
|
-
if (newIsPlaying) {
|
|
91
|
-
setStatus(__1.PlayerStatus.PLAYING);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
setStatus(__1.PlayerStatus.WAITING);
|
|
95
|
-
}
|
|
96
|
-
}));
|
|
97
|
-
return () => {
|
|
98
|
-
for (const sub of subs) {
|
|
99
|
-
sub.remove();
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
}, [player, playerEvent, setStatus, spurl]);
|
|
103
|
-
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: () => {
|
|
104
|
-
setFullscreen(true);
|
|
105
|
-
}, onFullscreenExit: () => {
|
|
106
|
-
setFullscreen(false);
|
|
107
|
-
}, allowsPictureInPicture: true, onLayout: handleLayout }) }));
|
|
108
|
-
}
|
|
109
|
-
function NativeWHEP() {
|
|
110
|
-
const selectedRendition = (0, __1.usePlayerStore)((x) => x.selectedRendition);
|
|
111
|
-
const src = (0, __1.usePlayerStore)((x) => x.src);
|
|
112
|
-
const { url } = (0, shared_1.srcToUrl)({ src: src, selectedRendition }, __1.PlayerProtocol.WEBRTC);
|
|
113
|
-
const [stream, stuck] = (0, use_webrtc_1.default)(url);
|
|
114
|
-
const status = (0, __1.usePlayerStore)((x) => x.status);
|
|
115
|
-
const setPlayerWidth = (0, __1.usePlayerStore)((x) => x.setPlayerWidth);
|
|
116
|
-
const setPlayerHeight = (0, __1.usePlayerStore)((x) => x.setPlayerHeight);
|
|
117
|
-
// PiP support: wire up videoRef (no direct ref for RTCView)
|
|
118
|
-
const setVideoRef = (0, __1.usePlayerStore)((x) => x.setVideoRef);
|
|
119
|
-
// State for live dimensions
|
|
120
|
-
const [dimensions, setDimensions] = (0, react_1.useState)({ width: 0, height: 0 });
|
|
121
|
-
const handleLayout = (0, react_1.useCallback)((event) => {
|
|
122
|
-
const { width, height } = event.nativeEvent.layout;
|
|
123
|
-
setDimensions({ width, height });
|
|
124
|
-
setPlayerWidth(width);
|
|
125
|
-
setPlayerHeight(height);
|
|
126
|
-
}, []);
|
|
127
|
-
const setStatus = (0, __1.usePlayerStore)((x) => x.setStatus);
|
|
128
|
-
const muted = (0, __1.usePlayerStore)((x) => x.muted);
|
|
129
|
-
const volume = (0, __1.usePlayerStore)((x) => x.volume);
|
|
130
|
-
(0, react_1.useEffect)(() => {
|
|
131
|
-
if (stuck && status === __1.PlayerStatus.PLAYING) {
|
|
132
|
-
console.log("setting status to stalled", status);
|
|
133
|
-
setStatus(__1.PlayerStatus.STALLED);
|
|
134
|
-
}
|
|
135
|
-
if (!stuck && status === __1.PlayerStatus.STALLED) {
|
|
136
|
-
console.log("setting status to playing", status);
|
|
137
|
-
setStatus(__1.PlayerStatus.PLAYING);
|
|
138
|
-
}
|
|
139
|
-
}, [stuck, status]);
|
|
140
|
-
const mediaStream = stream;
|
|
141
|
-
// useEffect(() => {
|
|
142
|
-
// if (!mediaStream) {
|
|
143
|
-
// setStatus(PlayerStatus.WAITING);
|
|
144
|
-
// return;
|
|
145
|
-
// }
|
|
146
|
-
// setStatus(PlayerStatus.PLAYING);
|
|
147
|
-
// }, [mediaStream, setStatus]);
|
|
148
|
-
(0, react_1.useEffect)(() => {
|
|
149
|
-
if (!mediaStream) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
mediaStream.getTracks().forEach((track) => {
|
|
153
|
-
if (track.kind === "audio") {
|
|
154
|
-
track._setVolume(muted ? 0 : volume);
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
}, [mediaStream, muted, volume]);
|
|
158
|
-
// Keep the playerStore videoRef in sync for PiP (if possible)
|
|
159
|
-
(0, react_1.useEffect)(() => {
|
|
160
|
-
if (typeof setVideoRef === "function") {
|
|
161
|
-
setVideoRef(null); // No direct ref for RTCView, but keep API consistent
|
|
162
|
-
}
|
|
163
|
-
}, [setVideoRef]);
|
|
164
|
-
if (!mediaStream) {
|
|
165
|
-
return (0, jsx_runtime_1.jsx)(__1.View, {});
|
|
166
|
-
}
|
|
167
|
-
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: {
|
|
168
|
-
width: 160,
|
|
169
|
-
height: 90,
|
|
170
|
-
}, style: {
|
|
171
|
-
minWidth: "100%",
|
|
172
|
-
minHeight: "100%",
|
|
173
|
-
flex: 1,
|
|
174
|
-
} }) }));
|
|
175
|
-
}
|
|
176
|
-
function NativeIngestPlayer() {
|
|
177
|
-
const ingestStarting = (0, __1.usePlayerStore)((x) => x.ingestStarting);
|
|
178
|
-
const ingestMediaSource = (0, __1.usePlayerStore)((x) => x.ingestMediaSource);
|
|
179
|
-
const ingestAutoStart = (0, __1.usePlayerStore)((x) => x.ingestAutoStart);
|
|
180
|
-
const setStatus = (0, __1.usePlayerStore)((x) => x.setStatus);
|
|
181
|
-
const setVideoRef = (0, __1.usePlayerStore)((x) => x.setVideoRef);
|
|
182
|
-
const [error, setError] = (0, react_1.useState)(null);
|
|
183
|
-
const ingestCamera = (0, __1.usePlayerStore)((x) => x.ingestCamera);
|
|
184
|
-
(0, react_1.useEffect)(() => {
|
|
185
|
-
setStatus(__1.PlayerStatus.PLAYING);
|
|
186
|
-
}, [setStatus]);
|
|
187
|
-
(0, react_1.useEffect)(() => {
|
|
188
|
-
if (typeof setVideoRef === "function") {
|
|
189
|
-
setVideoRef(null);
|
|
190
|
-
}
|
|
191
|
-
}, [setVideoRef]);
|
|
192
|
-
const url = (0, __1.useStreamplaceStore)((x) => x.url);
|
|
193
|
-
const [lms, setLocalMediaStream] = (0, react_1.useState)(null);
|
|
194
|
-
const [, setRemoteMediaStream] = (0, use_webrtc_1.useWebRTCIngest)({
|
|
195
|
-
endpoint: `${url}/api/ingest/webrtc`,
|
|
196
|
-
});
|
|
197
|
-
// Use lms directly as localMediaStream
|
|
198
|
-
const localMediaStream = lms;
|
|
199
|
-
(0, react_1.useEffect)(() => {
|
|
200
|
-
if (ingestMediaSource === __1.IngestMediaSource.DISPLAY) {
|
|
201
|
-
webrtc_primitives_native_1.mediaDevices
|
|
202
|
-
.getDisplayMedia()
|
|
203
|
-
.then((stream) => {
|
|
204
|
-
console.log("display media", stream);
|
|
205
|
-
setLocalMediaStream(stream);
|
|
206
|
-
})
|
|
207
|
-
.catch((e) => {
|
|
208
|
-
console.log("error getting display media", e);
|
|
209
|
-
console.error("error getting display media", e);
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
webrtc_primitives_native_1.mediaDevices
|
|
214
|
-
.getUserMedia({
|
|
215
|
-
audio: {
|
|
216
|
-
// deviceId: "audio-1",
|
|
217
|
-
// echoCancellation: true,
|
|
218
|
-
// autoGainControl: true,
|
|
219
|
-
// noiseSuppression: true,
|
|
220
|
-
// latency: false,
|
|
221
|
-
// channelCount: false,
|
|
222
|
-
},
|
|
223
|
-
video: {
|
|
224
|
-
facingMode: ingestCamera,
|
|
225
|
-
width: { min: 200, ideal: 1080, max: 2160 },
|
|
226
|
-
height: { min: 200, ideal: 1920, max: 3840 },
|
|
227
|
-
},
|
|
228
|
-
})
|
|
229
|
-
.then((stream) => {
|
|
230
|
-
setLocalMediaStream(stream);
|
|
231
|
-
let errs = [];
|
|
232
|
-
if (stream.getAudioTracks().length === 0) {
|
|
233
|
-
console.warn("No audio tracks found in user media stream");
|
|
234
|
-
errs.push("microphone");
|
|
235
|
-
}
|
|
236
|
-
if (stream.getVideoTracks().length === 0) {
|
|
237
|
-
console.warn("No video tracks found in user media stream");
|
|
238
|
-
errs.push("camera");
|
|
239
|
-
}
|
|
240
|
-
if (errs.length > 0) {
|
|
241
|
-
setError(new Error(`We could not access your ${errs.join(" and ")}. To stream, you need to give us permission to access these.`));
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
setError(null);
|
|
245
|
-
}
|
|
246
|
-
})
|
|
247
|
-
.catch((e) => {
|
|
248
|
-
console.error("error getting user media", e);
|
|
249
|
-
setError(new Error("We could not access your camera or microphone. To stream, you need to give us permission to access these."));
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
}, [ingestMediaSource, ingestCamera]);
|
|
253
|
-
(0, react_1.useEffect)(() => {
|
|
254
|
-
if (!ingestStarting && !ingestAutoStart) {
|
|
255
|
-
setRemoteMediaStream(null);
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
if (!localMediaStream) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
console.log("setting remote media stream", localMediaStream);
|
|
262
|
-
// @ts-expect-error: WebRTCMediaStream may not have all MediaStream properties, but is compatible for our use
|
|
263
|
-
setRemoteMediaStream(localMediaStream);
|
|
264
|
-
}, [localMediaStream, ingestStarting, ingestAutoStart, setRemoteMediaStream]);
|
|
265
|
-
if (!localMediaStream) {
|
|
266
|
-
return null;
|
|
267
|
-
}
|
|
268
|
-
if (error) {
|
|
269
|
-
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" })] }) }))] }));
|
|
270
|
-
}
|
|
271
|
-
return ((0, jsx_runtime_1.jsx)(react_native_webrtc_1.RTCView, { mirror: ingestCamera !== "environment", objectFit: "contain", streamURL: localMediaStream.toURL(), zOrder: 0, style: {
|
|
272
|
-
minWidth: "100%",
|
|
273
|
-
minHeight: "100%",
|
|
274
|
-
flex: 1,
|
|
275
|
-
} }));
|
|
276
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
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)({
|
|
8
|
-
done: false,
|
|
9
|
-
browserSupport: false,
|
|
10
|
-
rtcPeerConnection: false,
|
|
11
|
-
rtcSessionDescription: false,
|
|
12
|
-
getUserMedia: false,
|
|
13
|
-
getDisplayMedia: false,
|
|
14
|
-
errors: [],
|
|
15
|
-
warnings: [],
|
|
16
|
-
});
|
|
17
|
-
(0, react_1.useEffect)(() => {
|
|
18
|
-
const errors = [];
|
|
19
|
-
const warnings = [];
|
|
20
|
-
// Check if we're in a browser environment
|
|
21
|
-
if (typeof window === "undefined") {
|
|
22
|
-
errors.push("Running in non-browser environment");
|
|
23
|
-
setDiagnostics({
|
|
24
|
-
done: false,
|
|
25
|
-
browserSupport: false,
|
|
26
|
-
rtcPeerConnection: false,
|
|
27
|
-
rtcSessionDescription: false,
|
|
28
|
-
getUserMedia: false,
|
|
29
|
-
getDisplayMedia: false,
|
|
30
|
-
errors,
|
|
31
|
-
warnings,
|
|
32
|
-
});
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
// Check RTCPeerConnection support
|
|
36
|
-
const rtcPeerConnection = !!(window.RTCPeerConnection ||
|
|
37
|
-
window.webkitRTCPeerConnection ||
|
|
38
|
-
window.mozRTCPeerConnection);
|
|
39
|
-
if (!rtcPeerConnection) {
|
|
40
|
-
errors.push("RTCPeerConnection is not supported");
|
|
41
|
-
}
|
|
42
|
-
// Check RTCSessionDescription support
|
|
43
|
-
const rtcSessionDescription = !!(window.RTCSessionDescription ||
|
|
44
|
-
window.webkitRTCSessionDescription ||
|
|
45
|
-
window.mozRTCSessionDescription);
|
|
46
|
-
if (!rtcSessionDescription) {
|
|
47
|
-
errors.push("RTCSessionDescription is not supported");
|
|
48
|
-
}
|
|
49
|
-
// Check getUserMedia support
|
|
50
|
-
const getUserMedia = !!(navigator.mediaDevices?.getUserMedia ||
|
|
51
|
-
navigator.getUserMedia ||
|
|
52
|
-
navigator.webkitGetUserMedia ||
|
|
53
|
-
navigator.mozGetUserMedia);
|
|
54
|
-
if (!getUserMedia) {
|
|
55
|
-
warnings.push("getUserMedia is not supported - webcam features unavailable");
|
|
56
|
-
}
|
|
57
|
-
// Check getDisplayMedia support
|
|
58
|
-
const getDisplayMedia = !!navigator.mediaDevices?.getDisplayMedia;
|
|
59
|
-
if (!getDisplayMedia) {
|
|
60
|
-
warnings.push("getDisplayMedia is not supported - screen sharing unavailable");
|
|
61
|
-
}
|
|
62
|
-
// Check if running over HTTPS (required for some WebRTC features)
|
|
63
|
-
if (location.protocol !== "https:" &&
|
|
64
|
-
location.hostname !== "localhost" &&
|
|
65
|
-
location.hostname !== "127.0.0.1") {
|
|
66
|
-
warnings.push("WebRTC features may be limited over HTTP connections");
|
|
67
|
-
}
|
|
68
|
-
// Check browser-specific issues
|
|
69
|
-
const userAgent = navigator.userAgent.toLowerCase();
|
|
70
|
-
if (userAgent.includes("safari") && !userAgent.includes("chrome")) {
|
|
71
|
-
warnings.push("Safari may have limited WebRTC codec support");
|
|
72
|
-
}
|
|
73
|
-
const browserSupport = rtcPeerConnection && rtcSessionDescription;
|
|
74
|
-
setDiagnostics({
|
|
75
|
-
done: true,
|
|
76
|
-
browserSupport,
|
|
77
|
-
rtcPeerConnection,
|
|
78
|
-
rtcSessionDescription,
|
|
79
|
-
getUserMedia,
|
|
80
|
-
getDisplayMedia,
|
|
81
|
-
errors,
|
|
82
|
-
warnings,
|
|
83
|
-
});
|
|
84
|
-
}, []);
|
|
85
|
-
return diagnostics;
|
|
86
|
-
}
|
|
87
|
-
function logWebRTCDiagnostics() {
|
|
88
|
-
console.group("WebRTC Diagnostics");
|
|
89
|
-
// Log browser support
|
|
90
|
-
console.log("RTCPeerConnection:", !!window.RTCPeerConnection);
|
|
91
|
-
console.log("RTCSessionDescription:", !!window.RTCSessionDescription);
|
|
92
|
-
console.log("getUserMedia:", !!navigator.mediaDevices?.getUserMedia);
|
|
93
|
-
console.log("getDisplayMedia:", !!navigator.mediaDevices?.getDisplayMedia);
|
|
94
|
-
// Log browser info
|
|
95
|
-
console.log("User Agent:", navigator.userAgent);
|
|
96
|
-
console.log("Protocol:", location.protocol);
|
|
97
|
-
console.log("Host:", location.hostname);
|
|
98
|
-
// Test basic WebRTC functionality
|
|
99
|
-
if (window.RTCPeerConnection) {
|
|
100
|
-
try {
|
|
101
|
-
const pc = new RTCPeerConnection();
|
|
102
|
-
console.log("RTCPeerConnection creation: ✓ Success");
|
|
103
|
-
pc.close();
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
console.error("RTCPeerConnection creation: ✗ Failed", error);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
console.groupEnd();
|
|
110
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkWebRTCSupport = exports.mediaDevices = exports.WebRTCMediaStream = exports.RTCSessionDescription = exports.RTCPeerConnection = void 0;
|
|
4
|
-
// Browser compatibility checks for WebRTC
|
|
5
|
-
const checkWebRTCSupport = () => {
|
|
6
|
-
if (typeof window === "undefined") {
|
|
7
|
-
throw new Error("WebRTC is not available in non-browser environments");
|
|
8
|
-
}
|
|
9
|
-
if (!window.RTCPeerConnection) {
|
|
10
|
-
throw new Error("RTCPeerConnection is not supported in this browser. Please use a modern browser that supports WebRTC.");
|
|
11
|
-
}
|
|
12
|
-
if (!window.RTCSessionDescription) {
|
|
13
|
-
throw new Error("RTCSessionDescription is not supported in this browser. Please use a modern browser that supports WebRTC.");
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
exports.checkWebRTCSupport = checkWebRTCSupport;
|
|
17
|
-
// Check support immediately
|
|
18
|
-
try {
|
|
19
|
-
checkWebRTCSupport();
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
console.error("WebRTC Compatibility Error:", error.message);
|
|
23
|
-
}
|
|
24
|
-
exports.RTCPeerConnection = window.RTCPeerConnection;
|
|
25
|
-
exports.RTCSessionDescription = window.RTCSessionDescription;
|
|
26
|
-
exports.WebRTCMediaStream = window.MediaStream;
|
|
27
|
-
exports.mediaDevices = navigator.mediaDevices;
|
|
@@ -1,8 +0,0 @@
|
|
|
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,91 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ShareSheet = ShareSheet;
|
|
4
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const lucide_react_native_1 = require("lucide-react-native");
|
|
6
|
-
const react_1 = require("react");
|
|
7
|
-
const react_native_1 = require("react-native");
|
|
8
|
-
const theme_1 = require("../../lib/theme");
|
|
9
|
-
const livestream_store_1 = require("../../livestream-store");
|
|
10
|
-
const streamplace_store_1 = require("../../streamplace-store");
|
|
11
|
-
const bluesky_icon_1 = require("../icons/bluesky-icon");
|
|
12
|
-
const ui_1 = require("../ui");
|
|
13
|
-
function ShareSheet({ onShare } = {}) {
|
|
14
|
-
const profile = (0, livestream_store_1.useLivestreamStore)((x) => x.profile);
|
|
15
|
-
const [isCopying, setIsCopying] = (0, react_1.useState)(false);
|
|
16
|
-
const url = (0, streamplace_store_1.useUrl)();
|
|
17
|
-
// Get the current stream URL
|
|
18
|
-
const getStreamUrl = (0, react_1.useCallback)(() => {
|
|
19
|
-
return url + (profile ? `/@${profile.handle}` : "");
|
|
20
|
-
}, [profile]);
|
|
21
|
-
// Get the embed URL
|
|
22
|
-
const getEmbedUrl = (0, react_1.useCallback)(() => {
|
|
23
|
-
return url + (profile ? `/embed/${profile.handle}` : "");
|
|
24
|
-
}, [profile]);
|
|
25
|
-
// Get embed code
|
|
26
|
-
const getEmbedCode = (0, react_1.useCallback)(() => {
|
|
27
|
-
const embedUrl = getEmbedUrl();
|
|
28
|
-
return `<iframe src="${embedUrl}" width="640" height="360" frameborder="0" allowfullscreen></iframe>`;
|
|
29
|
-
}, [getEmbedUrl]);
|
|
30
|
-
// Copy to clipboard handler
|
|
31
|
-
const copyToClipboard = (0, react_1.useCallback)(async (text, label) => {
|
|
32
|
-
setIsCopying(true);
|
|
33
|
-
try {
|
|
34
|
-
if (react_native_1.Platform.OS === "web") {
|
|
35
|
-
await navigator.clipboard.writeText(text);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
react_native_1.Clipboard.setString(text);
|
|
39
|
-
}
|
|
40
|
-
onShare?.(`copy_${label.toLowerCase().replace(/\s+/g, "_")}`, true);
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
onShare?.(`copy_${label.toLowerCase().replace(/\s+/g, "_")}`, false);
|
|
44
|
-
}
|
|
45
|
-
finally {
|
|
46
|
-
setIsCopying(false);
|
|
47
|
-
}
|
|
48
|
-
}, [onShare]);
|
|
49
|
-
// Share to Bluesky
|
|
50
|
-
const shareToBluesky = (0, react_1.useCallback)(() => {
|
|
51
|
-
const streamUrl = getStreamUrl();
|
|
52
|
-
const text = profile
|
|
53
|
-
? `Check out @${profile.handle} live on Streamplace! ${streamUrl}`
|
|
54
|
-
: `Check out this stream on Streamplace! ${streamUrl}`;
|
|
55
|
-
const blueskyUrl = `https://bsky.app/intent/compose?text=${encodeURIComponent(text)}`;
|
|
56
|
-
react_native_1.Linking.openURL(blueskyUrl);
|
|
57
|
-
onShare?.("share_bluesky", true);
|
|
58
|
-
}, [profile, getStreamUrl, onShare]);
|
|
59
|
-
// Share to Twitter/X
|
|
60
|
-
const shareToTwitter = (0, react_1.useCallback)(() => {
|
|
61
|
-
const streamUrl = getStreamUrl();
|
|
62
|
-
const text = profile
|
|
63
|
-
? `Check out @${profile.handle} live on Streamplace!`
|
|
64
|
-
: `Check out this stream on Streamplace!`;
|
|
65
|
-
const twitterUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(streamUrl)}`;
|
|
66
|
-
react_native_1.Linking.openURL(twitterUrl);
|
|
67
|
-
onShare?.("share_twitter", true);
|
|
68
|
-
}, [profile, getStreamUrl, onShare]);
|
|
69
|
-
// Native share (mobile)
|
|
70
|
-
const nativeShare = (0, react_1.useCallback)(async () => {
|
|
71
|
-
const streamUrl = getStreamUrl();
|
|
72
|
-
const text = profile
|
|
73
|
-
? `Check out @${profile.handle} live on Streamplace!`
|
|
74
|
-
: `Check out this stream on Streamplace!`;
|
|
75
|
-
if (react_native_1.Platform.OS === "web" && navigator.share) {
|
|
76
|
-
try {
|
|
77
|
-
await navigator.share({
|
|
78
|
-
title: "Streamplace",
|
|
79
|
-
text: text,
|
|
80
|
-
url: streamUrl,
|
|
81
|
-
});
|
|
82
|
-
onShare?.("share_native", true);
|
|
83
|
-
}
|
|
84
|
-
catch (error) {
|
|
85
|
-
// User cancelled or error occurred
|
|
86
|
-
onShare?.("share_native", false);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}, [profile, getStreamUrl, onShare]);
|
|
90
|
-
return ((0, jsx_runtime_1.jsxs)(ui_1.DropdownMenu, { children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuTrigger, { children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Share2, { color: theme_1.colors.gray[200] }) }), (0, jsx_runtime_1.jsxs)(ui_1.ResponsiveDropdownMenuContent, { children: [(0, jsx_runtime_1.jsxs)(ui_1.DropdownMenuGroup, { title: "Share", children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: shareToBluesky, closeOnPress: true, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(bluesky_icon_1.BlueskyIcon, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Share to Bluesky" })] }) }), react_native_1.Platform.OS !== "web" || (navigator && navigator.share) ? ((0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: nativeShare, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Share2, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "More Options..." })] }) })) : null] }), (0, jsx_runtime_1.jsxs)(ui_1.DropdownMenuGroup, { title: "Copy", children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: () => copyToClipboard(getStreamUrl(), "Stream link"), disabled: isCopying, closeOnPress: true, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Link2, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Copy Link" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuSeparator, {}), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: () => copyToClipboard(getEmbedCode(), "Embed code"), disabled: isCopying, closeOnPress: true, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Code, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Copy Embed Code" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuSeparator, {}), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { closeOnPress: true, onPress: () => copyToClipboard(getEmbedUrl(), "Embed URL"), disabled: isCopying, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Copy, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Copy Embed URL" })] }) })] })] })] }));
|
|
91
|
-
}
|