@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,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useCameraToggle = useCameraToggle;
|
|
4
|
-
const player_store_1 = require("../player-store");
|
|
5
|
-
function useCameraToggle() {
|
|
6
|
-
const ingestCamera = (0, player_store_1.usePlayerStore)((x) => x.ingestCamera);
|
|
7
|
-
const setIngestCamera = (0, player_store_1.usePlayerStore)((x) => x.setIngestCamera);
|
|
8
|
-
const doSetIngestCamera = () => {
|
|
9
|
-
setIngestCamera(ingestCamera === "user" ? "environment" : "user");
|
|
10
|
-
};
|
|
11
|
-
return { ingestCamera, doSetIngestCamera };
|
|
12
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useKeyboard = useKeyboard;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const react_native_1 = require("react-native");
|
|
6
|
-
function useKeyboard() {
|
|
7
|
-
const [isKeyboardVisible, setIsKeyboardVisible] = (0, react_1.useState)(false);
|
|
8
|
-
const [keyboardHeight, setKeyboardHeight] = (0, react_1.useState)(0);
|
|
9
|
-
(0, react_1.useEffect)(() => {
|
|
10
|
-
const willShowSubscription = react_native_1.Keyboard.addListener("keyboardWillShow", (e) => {
|
|
11
|
-
// setIsKeyboardVisible(true);
|
|
12
|
-
setKeyboardHeight(e.endCoordinates.height);
|
|
13
|
-
console.log("keyboardWillShow", e.endCoordinates.height);
|
|
14
|
-
});
|
|
15
|
-
const willHideSubscription = react_native_1.Keyboard.addListener("keyboardWillHide", (e) => {
|
|
16
|
-
// setIsKeyboardVisible(false);
|
|
17
|
-
setKeyboardHeight(0);
|
|
18
|
-
console.log("keyboardWillHide", e.endCoordinates.height);
|
|
19
|
-
});
|
|
20
|
-
const showSubscription = react_native_1.Keyboard.addListener("keyboardDidShow", (e) => {
|
|
21
|
-
setIsKeyboardVisible(true);
|
|
22
|
-
setKeyboardHeight(e.endCoordinates.height);
|
|
23
|
-
console.log("keyboardDidShow", e.endCoordinates.height);
|
|
24
|
-
});
|
|
25
|
-
const hideSubscription = react_native_1.Keyboard.addListener("keyboardDidHide", () => {
|
|
26
|
-
setIsKeyboardVisible(false);
|
|
27
|
-
setKeyboardHeight(0);
|
|
28
|
-
});
|
|
29
|
-
return () => {
|
|
30
|
-
showSubscription.remove();
|
|
31
|
-
hideSubscription.remove();
|
|
32
|
-
willShowSubscription.remove();
|
|
33
|
-
};
|
|
34
|
-
}, []);
|
|
35
|
-
return { isKeyboardVisible, keyboardHeight };
|
|
36
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useKeyboardSlide = useKeyboardSlide;
|
|
4
|
-
const useKeyboard_1 = require("../hooks/useKeyboard");
|
|
5
|
-
const useOuterAndInnerDimensions_1 = require("../hooks/useOuterAndInnerDimensions");
|
|
6
|
-
function useKeyboardSlide() {
|
|
7
|
-
const { keyboardHeight } = (0, useKeyboard_1.useKeyboard)();
|
|
8
|
-
const { outerHeight, innerHeight } = (0, useOuterAndInnerDimensions_1.useOuterAndInnerDimensions)();
|
|
9
|
-
let slideKeyboard = 0;
|
|
10
|
-
if (keyboardHeight > 0) {
|
|
11
|
-
slideKeyboard = -keyboardHeight + (outerHeight - innerHeight);
|
|
12
|
-
}
|
|
13
|
-
return { keyboardHeight, slideKeyboard };
|
|
14
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useLivestreamInfo = useLivestreamInfo;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const livestream_store_1 = require("../livestream-store");
|
|
6
|
-
const player_store_1 = require("../player-store");
|
|
7
|
-
const streamplace_store_1 = require("../streamplace-store");
|
|
8
|
-
function useLivestreamInfo() {
|
|
9
|
-
const ingest = (0, player_store_1.usePlayerStore)((x) => x.ingestConnectionState);
|
|
10
|
-
const profile = (0, livestream_store_1.useLivestreamStore)((x) => x.profile);
|
|
11
|
-
const ingestStarting = (0, player_store_1.usePlayerStore)((x) => x.ingestStarting);
|
|
12
|
-
const setIngestStarting = (0, player_store_1.usePlayerStore)((x) => x.setIngestStarting);
|
|
13
|
-
const setIngestLive = (0, player_store_1.usePlayerStore)((x) => x.setIngestLive);
|
|
14
|
-
const createStreamRecord = (0, streamplace_store_1.useCreateStreamRecord)();
|
|
15
|
-
const [title, setTitle] = (0, react_1.useState)("");
|
|
16
|
-
const [showCountdown, setShowCountdown] = (0, react_1.useState)(false);
|
|
17
|
-
const [recordSubmitted, setRecordSubmitted] = (0, react_1.useState)(false);
|
|
18
|
-
const handleSubmit = async () => {
|
|
19
|
-
try {
|
|
20
|
-
if (title !== "") {
|
|
21
|
-
setRecordSubmitted(true);
|
|
22
|
-
await createStreamRecord(title);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
console.error("Error creating livestream:", error);
|
|
27
|
-
throw new Error("Failed to create livestream record");
|
|
28
|
-
}
|
|
29
|
-
finally {
|
|
30
|
-
setRecordSubmitted(false);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
const toggleGoLive = (keyboardHeight, closeKeyboard) => {
|
|
34
|
-
if (!ingestStarting) {
|
|
35
|
-
// Optionally close keyboard if provided
|
|
36
|
-
if (closeKeyboard)
|
|
37
|
-
closeKeyboard();
|
|
38
|
-
setShowCountdown(true);
|
|
39
|
-
setIngestStarting(true);
|
|
40
|
-
setIngestLive(true);
|
|
41
|
-
// wait ~3 seconds before announcing
|
|
42
|
-
setTimeout(() => {
|
|
43
|
-
handleSubmit();
|
|
44
|
-
}, 3000);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
setIngestStarting(false);
|
|
48
|
-
setIngestLive(false);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
return {
|
|
52
|
-
ingest,
|
|
53
|
-
profile,
|
|
54
|
-
title,
|
|
55
|
-
setTitle,
|
|
56
|
-
showCountdown,
|
|
57
|
-
setShowCountdown,
|
|
58
|
-
recordSubmitted,
|
|
59
|
-
setRecordSubmitted,
|
|
60
|
-
ingestStarting,
|
|
61
|
-
setIngestStarting,
|
|
62
|
-
handleSubmit,
|
|
63
|
-
toggleGoLive,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useOuterAndInnerDimensions = useOuterAndInnerDimensions;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
function useOuterAndInnerDimensions() {
|
|
6
|
-
const [outerDimensions, setOuterDimensions] = (0, react_1.useState)({
|
|
7
|
-
width: 0,
|
|
8
|
-
height: 0,
|
|
9
|
-
});
|
|
10
|
-
const [innerDimensions, setInnerDimensions] = (0, react_1.useState)({
|
|
11
|
-
width: 0,
|
|
12
|
-
height: 0,
|
|
13
|
-
});
|
|
14
|
-
const onOuterLayout = (0, react_1.useCallback)((event) => {
|
|
15
|
-
const { width, height } = event.nativeEvent.layout;
|
|
16
|
-
setOuterDimensions({ width, height });
|
|
17
|
-
}, []);
|
|
18
|
-
const onInnerLayout = (0, react_1.useCallback)((event) => {
|
|
19
|
-
const { width, height } = event.nativeEvent.layout;
|
|
20
|
-
setInnerDimensions({ width, height });
|
|
21
|
-
}, []);
|
|
22
|
-
return {
|
|
23
|
-
outerWidth: outerDimensions.width,
|
|
24
|
-
outerHeight: outerDimensions.height,
|
|
25
|
-
innerWidth: innerDimensions.width,
|
|
26
|
-
innerHeight: innerDimensions.height,
|
|
27
|
-
onOuterLayout,
|
|
28
|
-
onInnerLayout,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.usePlayerDimensions = usePlayerDimensions;
|
|
4
|
-
const react_native_1 = require("react-native");
|
|
5
|
-
const player_store_1 = require("../player-store");
|
|
6
|
-
/**
|
|
7
|
-
* usePlayerDimensions
|
|
8
|
-
* Returns player and device dimensions, and whether the player aspect ratio is greater than the device's.
|
|
9
|
-
*/
|
|
10
|
-
function usePlayerDimensions() {
|
|
11
|
-
const { width, height } = react_native_1.Dimensions.get("window");
|
|
12
|
-
const pHeight = Number((0, player_store_1.usePlayerStore)((x) => x.playerHeight)) || 0;
|
|
13
|
-
const pWidth = Number((0, player_store_1.usePlayerStore)((x) => x.playerWidth)) || 0;
|
|
14
|
-
const isPlayerRatioGreater = pHeight > 0 && pWidth > 0 ? pWidth / pHeight > width / height : false;
|
|
15
|
-
return {
|
|
16
|
-
width,
|
|
17
|
-
height,
|
|
18
|
-
pWidth,
|
|
19
|
-
pHeight,
|
|
20
|
-
isPlayerRatioGreater,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.usePointerDevice = usePointerDevice;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const react_native_1 = require("react-native");
|
|
6
|
-
/**
|
|
7
|
-
* Hook to detect if the device is primarily mouse-driven vs touch-driven
|
|
8
|
-
* Uses CSS media queries to detect hover and pointer capabilities
|
|
9
|
-
*/
|
|
10
|
-
function usePointerDevice() {
|
|
11
|
-
const [pointerDevice, setPointerDevice] = (0, react_1.useState)(() => {
|
|
12
|
-
// Default values for non-web platforms
|
|
13
|
-
if (react_native_1.Platform.OS !== "web") {
|
|
14
|
-
return {
|
|
15
|
-
hasHover: false,
|
|
16
|
-
hasFinePointer: false,
|
|
17
|
-
isMouseDriven: false,
|
|
18
|
-
isTouchDriven: true,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
// Initial web detection
|
|
22
|
-
if (typeof window !== "undefined" && window.matchMedia) {
|
|
23
|
-
const hasHover = window.matchMedia("(hover: hover)").matches;
|
|
24
|
-
const hasFinePointer = window.matchMedia("(pointer: fine)").matches;
|
|
25
|
-
return {
|
|
26
|
-
hasHover,
|
|
27
|
-
hasFinePointer,
|
|
28
|
-
isMouseDriven: hasHover && hasFinePointer,
|
|
29
|
-
isTouchDriven: !hasHover || !hasFinePointer,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
// Fallback for SSR or environments without matchMedia
|
|
33
|
-
return {
|
|
34
|
-
hasHover: false,
|
|
35
|
-
hasFinePointer: false,
|
|
36
|
-
isMouseDriven: false,
|
|
37
|
-
isTouchDriven: true,
|
|
38
|
-
};
|
|
39
|
-
});
|
|
40
|
-
(0, react_1.useEffect)(() => {
|
|
41
|
-
// Only run on web platforms
|
|
42
|
-
if (react_native_1.Platform.OS !== "web" ||
|
|
43
|
-
typeof window === "undefined" ||
|
|
44
|
-
!window.matchMedia) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const hoverQuery = window.matchMedia("(hover: hover)");
|
|
48
|
-
const pointerQuery = window.matchMedia("(pointer: fine)");
|
|
49
|
-
const updatePointerDevice = () => {
|
|
50
|
-
const hasHover = hoverQuery.matches;
|
|
51
|
-
const hasFinePointer = pointerQuery.matches;
|
|
52
|
-
setPointerDevice({
|
|
53
|
-
hasHover,
|
|
54
|
-
hasFinePointer,
|
|
55
|
-
isMouseDriven: hasHover && hasFinePointer,
|
|
56
|
-
isTouchDriven: !hasHover || !hasFinePointer,
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
// Set up listeners for media query changes
|
|
60
|
-
hoverQuery.addEventListener("change", updatePointerDevice);
|
|
61
|
-
pointerQuery.addEventListener("change", updatePointerDevice);
|
|
62
|
-
// Initial update
|
|
63
|
-
updatePointerDevice();
|
|
64
|
-
// Cleanup
|
|
65
|
-
return () => {
|
|
66
|
-
hoverQuery.removeEventListener("change", updatePointerDevice);
|
|
67
|
-
pointerQuery.removeEventListener("change", updatePointerDevice);
|
|
68
|
-
};
|
|
69
|
-
}, []);
|
|
70
|
-
return pointerDevice;
|
|
71
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useSegmentDimensions = useSegmentDimensions;
|
|
4
|
-
const livestream_store_1 = require("../livestream-store");
|
|
5
|
-
function useSegmentDimensions() {
|
|
6
|
-
const latestSegment = (0, livestream_store_1.useLivestreamStore)((x) => x.segment);
|
|
7
|
-
let seg = latestSegment?.video && latestSegment.video[0];
|
|
8
|
-
let ratio = {
|
|
9
|
-
height: seg?.height || 0,
|
|
10
|
-
width: seg?.width || 0,
|
|
11
|
-
};
|
|
12
|
-
return {
|
|
13
|
-
isPlayerRatioGreater: ratio.width > ratio.height,
|
|
14
|
-
height: ratio.height,
|
|
15
|
-
width: ratio.width,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useSegmentTiming = useSegmentTiming;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const livestream_store_1 = require("../livestream-store");
|
|
6
|
-
function getLiveConnectionQuality(timeBetweenSegments, range, numOfSegments = 1) {
|
|
7
|
-
if (timeBetweenSegments === null || range === null)
|
|
8
|
-
return "poor";
|
|
9
|
-
if (timeBetweenSegments <= 1500 && range <= (1500 * 60) / numOfSegments) {
|
|
10
|
-
return "good";
|
|
11
|
-
}
|
|
12
|
-
if (timeBetweenSegments <= 3000 && range <= (3000 * 60) / numOfSegments) {
|
|
13
|
-
return "degraded";
|
|
14
|
-
}
|
|
15
|
-
return "poor";
|
|
16
|
-
}
|
|
17
|
-
function useSegmentTiming() {
|
|
18
|
-
const latestSegment = (0, livestream_store_1.useLivestreamStore)((x) => x.segment);
|
|
19
|
-
const [segmentDeltas, setSegmentDeltas] = (0, react_1.useState)([]);
|
|
20
|
-
const prevSegmentRef = (0, react_1.useRef)();
|
|
21
|
-
const prevTimestampRef = (0, react_1.useRef)(null);
|
|
22
|
-
// Dummy state to force update every second
|
|
23
|
-
const [, setNow] = (0, react_1.useState)(Date.now());
|
|
24
|
-
(0, react_1.useEffect)(() => {
|
|
25
|
-
const interval = setInterval(() => {
|
|
26
|
-
setNow(Date.now());
|
|
27
|
-
}, 1000);
|
|
28
|
-
return () => clearInterval(interval);
|
|
29
|
-
}, []);
|
|
30
|
-
(0, react_1.useEffect)(() => {
|
|
31
|
-
if (latestSegment && prevSegmentRef.current !== latestSegment) {
|
|
32
|
-
const now = Date.now();
|
|
33
|
-
if (prevTimestampRef.current !== null) {
|
|
34
|
-
const delta = now - prevTimestampRef.current;
|
|
35
|
-
// Only store the last 25 deltas
|
|
36
|
-
setSegmentDeltas((prev) => [...prev, delta].slice(-25));
|
|
37
|
-
}
|
|
38
|
-
prevTimestampRef.current = now;
|
|
39
|
-
prevSegmentRef.current = latestSegment;
|
|
40
|
-
}
|
|
41
|
-
}, [latestSegment]);
|
|
42
|
-
// The most recent time between segments
|
|
43
|
-
const timeBetweenSegments = segmentDeltas.length > 0
|
|
44
|
-
? segmentDeltas[segmentDeltas.length - 1]
|
|
45
|
-
: prevTimestampRef.current
|
|
46
|
-
? Date.now() - prevTimestampRef.current
|
|
47
|
-
: null;
|
|
48
|
-
// Calculate mean and range of deltas
|
|
49
|
-
const mean = segmentDeltas.length > 0
|
|
50
|
-
? Math.round(segmentDeltas.reduce((acc, curr) => acc + curr, 0) /
|
|
51
|
-
segmentDeltas.length)
|
|
52
|
-
: null;
|
|
53
|
-
const range = segmentDeltas.length > 0
|
|
54
|
-
? Math.max(...segmentDeltas) - Math.min(...segmentDeltas)
|
|
55
|
-
: null;
|
|
56
|
-
let to_ret = {
|
|
57
|
-
segmentDeltas,
|
|
58
|
-
timeBetweenSegments,
|
|
59
|
-
mean,
|
|
60
|
-
range,
|
|
61
|
-
connectionQuality: "poor",
|
|
62
|
-
};
|
|
63
|
-
to_ret.connectionQuality = getLiveConnectionQuality(timeBetweenSegments, range, segmentDeltas.length);
|
|
64
|
-
return to_ret;
|
|
65
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Dashboard = exports.VideoRetry = exports.zero = exports.ui = exports.PlayerUI = exports.Player = exports.usePlayerContext = exports.withPlayerProvider = exports.PlayerProvider = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
// barrel file :)
|
|
6
|
-
tslib_1.__exportStar(require("./livestream-provider"), exports);
|
|
7
|
-
tslib_1.__exportStar(require("./livestream-store"), exports);
|
|
8
|
-
tslib_1.__exportStar(require("./player-store"), exports);
|
|
9
|
-
tslib_1.__exportStar(require("./streamplace-provider"), exports);
|
|
10
|
-
tslib_1.__exportStar(require("./streamplace-store"), exports);
|
|
11
|
-
var player_provider_1 = require("./player-store/player-provider");
|
|
12
|
-
Object.defineProperty(exports, "PlayerProvider", { enumerable: true, get: function () { return player_provider_1.PlayerProvider; } });
|
|
13
|
-
Object.defineProperty(exports, "withPlayerProvider", { enumerable: true, get: function () { return player_provider_1.withPlayerProvider; } });
|
|
14
|
-
var player_store_1 = require("./player-store/player-store");
|
|
15
|
-
Object.defineProperty(exports, "usePlayerContext", { enumerable: true, get: function () { return player_store_1.usePlayerContext; } });
|
|
16
|
-
var player_1 = require("./components/mobile-player/player");
|
|
17
|
-
Object.defineProperty(exports, "Player", { enumerable: true, get: function () { return player_1.Player; } });
|
|
18
|
-
Object.defineProperty(exports, "PlayerUI", { enumerable: true, get: function () { return player_1.PlayerUI; } });
|
|
19
|
-
exports.ui = tslib_1.__importStar(require("./components/ui"));
|
|
20
|
-
tslib_1.__exportStar(require("./components/ui"), exports);
|
|
21
|
-
exports.zero = tslib_1.__importStar(require("./ui"));
|
|
22
|
-
tslib_1.__exportStar(require("./hooks"), exports);
|
|
23
|
-
// Theme system exports
|
|
24
|
-
tslib_1.__exportStar(require("./lib/theme"), exports);
|
|
25
|
-
tslib_1.__exportStar(require("./components/chat/chat"), exports);
|
|
26
|
-
tslib_1.__exportStar(require("./components/chat/chat-box"), exports);
|
|
27
|
-
tslib_1.__exportStar(require("./components/chat/system-message"), exports);
|
|
28
|
-
var video_retry_1 = require("./components/mobile-player/video-retry");
|
|
29
|
-
Object.defineProperty(exports, "VideoRetry", { enumerable: true, get: function () { return tslib_1.__importDefault(video_retry_1).default; } });
|
|
30
|
-
tslib_1.__exportStar(require("./lib/system-messages"), exports);
|
|
31
|
-
tslib_1.__exportStar(require("./components/share/sharesheet"), exports);
|
|
32
|
-
tslib_1.__exportStar(require("./components/keep-awake"), exports);
|
|
33
|
-
// Dashboard components
|
|
34
|
-
exports.Dashboard = tslib_1.__importStar(require("./components/dashboard"));
|
package/dist/lib/facet.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.segmentize = void 0;
|
|
4
|
-
const segment = (text, features) => {
|
|
5
|
-
return { text, features: text.length > 0 ? features : undefined };
|
|
6
|
-
};
|
|
7
|
-
const segmentize = (text, facets) => {
|
|
8
|
-
if (facets === undefined || facets.length === 0) {
|
|
9
|
-
return [segment(text, undefined)];
|
|
10
|
-
}
|
|
11
|
-
const segments = [];
|
|
12
|
-
const utf16Length = text.length;
|
|
13
|
-
let utf16Cursor = 0;
|
|
14
|
-
let utf8Cursor = 0;
|
|
15
|
-
const advanceCursor = (startUtf16, endUtf8) => {
|
|
16
|
-
let curs = startUtf16;
|
|
17
|
-
// Fast-path for entirely ASCII text
|
|
18
|
-
const isLikelyAsciiText = text.charCodeAt(curs) < 0x80;
|
|
19
|
-
if (isLikelyAsciiText) {
|
|
20
|
-
curs += 1;
|
|
21
|
-
utf8Cursor += 1;
|
|
22
|
-
// SIMD-like batch processing
|
|
23
|
-
while (utf8Cursor + 8 <= endUtf8 && curs + 8 <= utf16Length) {
|
|
24
|
-
const char1 = text.charCodeAt(curs);
|
|
25
|
-
const char2 = text.charCodeAt(curs + 1);
|
|
26
|
-
const char3 = text.charCodeAt(curs + 2);
|
|
27
|
-
const char4 = text.charCodeAt(curs + 3);
|
|
28
|
-
const char5 = text.charCodeAt(curs + 4);
|
|
29
|
-
const char6 = text.charCodeAt(curs + 5);
|
|
30
|
-
const char7 = text.charCodeAt(curs + 6);
|
|
31
|
-
const char8 = text.charCodeAt(curs + 7);
|
|
32
|
-
if ((char1 | char2 | char3 | char4 | char5 | char6 | char7 | char8) <
|
|
33
|
-
0x80) {
|
|
34
|
-
curs += 8;
|
|
35
|
-
utf8Cursor += 8;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// Process remaining characters individually
|
|
42
|
-
while (utf8Cursor < endUtf8 && curs < utf16Length) {
|
|
43
|
-
const code = text.charCodeAt(curs);
|
|
44
|
-
if (code < 0x80) {
|
|
45
|
-
curs += 1;
|
|
46
|
-
utf8Cursor += 1;
|
|
47
|
-
}
|
|
48
|
-
else if (code < 0x800) {
|
|
49
|
-
curs += 1;
|
|
50
|
-
utf8Cursor += 2;
|
|
51
|
-
}
|
|
52
|
-
else if (code < 0xd800 || code > 0xdbff) {
|
|
53
|
-
curs += 1;
|
|
54
|
-
utf8Cursor += 3;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
curs += 2;
|
|
58
|
-
utf8Cursor += 4;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return curs;
|
|
62
|
-
};
|
|
63
|
-
// Process facets
|
|
64
|
-
for (let idx = 0, len = facets.length; idx < len; idx++) {
|
|
65
|
-
const facet = facets[idx];
|
|
66
|
-
const { byteStart, byteEnd } = facet.index;
|
|
67
|
-
const features = facet.features;
|
|
68
|
-
if (byteStart > byteEnd || features.length === 0) {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
if (utf8Cursor < byteStart) {
|
|
72
|
-
const nextUtf16Cursor = advanceCursor(utf16Cursor, byteStart);
|
|
73
|
-
if (nextUtf16Cursor > utf16Cursor) {
|
|
74
|
-
segments.push(segment(text.slice(utf16Cursor, nextUtf16Cursor), undefined));
|
|
75
|
-
}
|
|
76
|
-
utf16Cursor = nextUtf16Cursor;
|
|
77
|
-
}
|
|
78
|
-
{
|
|
79
|
-
const nextUtf16Cursor = advanceCursor(utf16Cursor, byteEnd);
|
|
80
|
-
if (nextUtf16Cursor > utf16Cursor) {
|
|
81
|
-
segments.push(segment(text.slice(utf16Cursor, nextUtf16Cursor), features));
|
|
82
|
-
}
|
|
83
|
-
utf16Cursor = nextUtf16Cursor;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Handle remaining text
|
|
87
|
-
if (utf16Cursor < utf16Length) {
|
|
88
|
-
segments.push(segment(text.slice(utf16Cursor), undefined));
|
|
89
|
-
}
|
|
90
|
-
return segments;
|
|
91
|
-
};
|
|
92
|
-
exports.segmentize = segmentize;
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseSystemMessageMetadata = exports.getSystemMessageType = exports.isSystemMessage = exports.SystemMessages = exports.createSystemMessage = exports.SystemMessageType = void 0;
|
|
4
|
-
var SystemMessageType;
|
|
5
|
-
(function (SystemMessageType) {
|
|
6
|
-
SystemMessageType["stream_start"] = "stream_start";
|
|
7
|
-
SystemMessageType["stream_end"] = "stream_end";
|
|
8
|
-
SystemMessageType["notification"] = "notification";
|
|
9
|
-
})(SystemMessageType || (exports.SystemMessageType = SystemMessageType = {}));
|
|
10
|
-
/**
|
|
11
|
-
* Creates a system message with the proper structure
|
|
12
|
-
* @param type The type of system message
|
|
13
|
-
* @param text The message text
|
|
14
|
-
* @param metadata Optional metadata for the message
|
|
15
|
-
* @returns A properly formatted ChatMessageViewHydrated object
|
|
16
|
-
*/
|
|
17
|
-
const createSystemMessage = (type, text, metadata, date = new Date()) => {
|
|
18
|
-
const now = date;
|
|
19
|
-
return {
|
|
20
|
-
uri: `at://did:sys:system/place.stream.chat.message/${now.getTime()}`,
|
|
21
|
-
cid: `system-${now.getTime()}`,
|
|
22
|
-
author: {
|
|
23
|
-
did: "did:sys:system",
|
|
24
|
-
handle: type, // Use handle to specify the type of system message
|
|
25
|
-
},
|
|
26
|
-
record: {
|
|
27
|
-
text,
|
|
28
|
-
createdAt: now.toISOString(),
|
|
29
|
-
streamer: "system",
|
|
30
|
-
$type: "place.stream.chat.message",
|
|
31
|
-
},
|
|
32
|
-
indexedAt: now.toISOString(),
|
|
33
|
-
chatProfile: {
|
|
34
|
-
color: { red: 128, green: 128, blue: 128 }, // Gray color for system messages
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
exports.createSystemMessage = createSystemMessage;
|
|
39
|
-
/**
|
|
40
|
-
* System message factory functions for common scenarios
|
|
41
|
-
*/
|
|
42
|
-
exports.SystemMessages = {
|
|
43
|
-
streamStart: (streamerName) => (0, exports.createSystemMessage)(SystemMessageType.stream_start, `Now streaming - ${streamerName}`, {
|
|
44
|
-
streamerName,
|
|
45
|
-
}),
|
|
46
|
-
// technically, streams can't 'end' on Streamplace
|
|
47
|
-
// possibly we could use deleting or editing streams (`endedAt` param) for this?
|
|
48
|
-
streamEnd: (duration) => (0, exports.createSystemMessage)(SystemMessageType.stream_end, duration ? `Stream has ended. Duration: ${duration}` : "Stream has ended", { duration }),
|
|
49
|
-
notification: (message) => (0, exports.createSystemMessage)(SystemMessageType.notification, message),
|
|
50
|
-
};
|
|
51
|
-
/**
|
|
52
|
-
* Checks if a message is a system message
|
|
53
|
-
* @param message The message to check
|
|
54
|
-
* @returns True if the message is a system message
|
|
55
|
-
*/
|
|
56
|
-
const isSystemMessage = (message) => {
|
|
57
|
-
return message.author.did === "did:sys:system";
|
|
58
|
-
};
|
|
59
|
-
exports.isSystemMessage = isSystemMessage;
|
|
60
|
-
/**
|
|
61
|
-
* Gets the system message type from a message
|
|
62
|
-
* @param message The message to check
|
|
63
|
-
* @returns The system message type or null if not a system message
|
|
64
|
-
*/
|
|
65
|
-
const getSystemMessageType = (message) => {
|
|
66
|
-
if (!(0, exports.isSystemMessage)(message)) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
return message.author.handle;
|
|
70
|
-
};
|
|
71
|
-
exports.getSystemMessageType = getSystemMessageType;
|
|
72
|
-
/**
|
|
73
|
-
* Parses metadata from a system message based on its type
|
|
74
|
-
* @param message The system message to parse
|
|
75
|
-
* @returns The parsed metadata
|
|
76
|
-
*/
|
|
77
|
-
const parseSystemMessageMetadata = (message) => {
|
|
78
|
-
const metadata = {};
|
|
79
|
-
const type = (0, exports.getSystemMessageType)(message);
|
|
80
|
-
const text = message.record.text;
|
|
81
|
-
if (!type)
|
|
82
|
-
return metadata;
|
|
83
|
-
switch (type) {
|
|
84
|
-
case "stream_end": {
|
|
85
|
-
const durationMatch = text.match(/Duration:\s*(\d+:\d+(?::\d+)?)/);
|
|
86
|
-
if (durationMatch) {
|
|
87
|
-
metadata.duration = durationMatch[1];
|
|
88
|
-
}
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
case "stream_start": {
|
|
92
|
-
const streamerMatch = text.match(/^(.+?)\s+is now live!/);
|
|
93
|
-
if (streamerMatch) {
|
|
94
|
-
metadata.streamerName = streamerMatch[1];
|
|
95
|
-
}
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return metadata;
|
|
100
|
-
};
|
|
101
|
-
exports.parseSystemMessageMetadata = parseSystemMessageMetadata;
|