@streamplace/components 0.7.18 → 0.7.21
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/assets/emoji-data.json +19371 -0
- package/dist/components/chat/chat-box.js +319 -0
- package/dist/components/chat/chat-message.js +87 -0
- package/dist/components/chat/chat.js +150 -0
- package/dist/components/chat/emoji-suggestions.js +35 -0
- package/dist/components/chat/mention-suggestions.js +42 -0
- package/dist/components/chat/mod-view.js +112 -0
- package/dist/components/chat/system-message.js +19 -0
- package/dist/components/dashboard/chat-panel.js +38 -0
- package/dist/components/dashboard/header.js +80 -0
- package/dist/components/dashboard/index.js +14 -0
- package/dist/components/dashboard/information-widget.js +234 -0
- package/dist/components/dashboard/mod-actions.js +71 -0
- package/dist/components/dashboard/problems.js +74 -0
- package/dist/components/icons/bluesky-icon.js +9 -0
- package/dist/components/keep-awake.js +7 -0
- package/dist/components/keep-awake.native.js +16 -0
- package/dist/components/mobile-player/fullscreen.js +76 -0
- package/dist/components/mobile-player/fullscreen.native.js +141 -0
- package/dist/components/mobile-player/player.js +94 -0
- package/dist/components/mobile-player/props.js +2 -0
- package/dist/components/mobile-player/shared.js +54 -0
- package/dist/components/mobile-player/ui/autoplay-button.js +68 -0
- package/dist/components/mobile-player/ui/countdown.js +83 -0
- package/dist/components/mobile-player/ui/index.js +12 -0
- package/dist/components/mobile-player/ui/input.js +42 -0
- package/dist/components/mobile-player/ui/metrics.js +44 -0
- package/dist/components/mobile-player/ui/report-modal.js +90 -0
- package/dist/components/mobile-player/ui/streamer-context-menu.js +7 -0
- package/dist/components/mobile-player/ui/streamer-loading-overlay.js +104 -0
- package/dist/components/mobile-player/ui/viewer-context-menu.js +51 -0
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js +49 -0
- package/dist/components/mobile-player/ui/viewers.js +23 -0
- package/dist/components/mobile-player/use-webrtc.js +243 -0
- package/dist/components/mobile-player/video-async.native.js +276 -0
- package/dist/components/mobile-player/video-retry.js +29 -0
- package/dist/components/mobile-player/video.js +475 -0
- package/dist/components/mobile-player/video.native.js +56 -0
- package/dist/components/mobile-player/webrtc-diagnostics.js +110 -0
- package/dist/components/mobile-player/webrtc-primitives.js +27 -0
- package/dist/components/mobile-player/webrtc-primitives.native.js +8 -0
- package/dist/components/share/sharesheet.js +91 -0
- package/dist/components/ui/button.js +223 -0
- package/dist/components/ui/dialog.js +206 -0
- package/dist/components/ui/dropdown.js +172 -0
- package/dist/components/ui/icons.js +25 -0
- package/dist/components/ui/index.js +34 -0
- package/dist/components/ui/info-box.js +31 -0
- package/dist/components/ui/info-row.js +23 -0
- package/dist/components/ui/input.js +205 -0
- package/dist/components/ui/loader.js +10 -0
- package/dist/components/ui/primitives/button.js +125 -0
- package/dist/components/ui/primitives/input.js +206 -0
- package/dist/components/ui/primitives/modal.js +206 -0
- package/dist/components/ui/primitives/text.js +292 -0
- package/dist/components/ui/resizeable.js +121 -0
- package/dist/components/ui/slider.js +5 -0
- package/dist/components/ui/text.js +177 -0
- package/dist/components/ui/textarea.js +19 -0
- package/dist/components/ui/toast.js +175 -0
- package/dist/components/ui/view.js +252 -0
- package/dist/hooks/index.js +14 -0
- package/dist/hooks/useAvatars.js +35 -0
- package/dist/hooks/useCameraToggle.js +12 -0
- package/dist/hooks/useKeyboard.js +36 -0
- package/dist/hooks/useKeyboardSlide.js +14 -0
- package/dist/hooks/useLivestreamInfo.js +69 -0
- package/dist/hooks/useOuterAndInnerDimensions.js +30 -0
- package/dist/hooks/usePlayerDimensions.js +22 -0
- package/dist/hooks/usePointerDevice.js +71 -0
- package/dist/hooks/useSegmentDimensions.js +17 -0
- package/dist/hooks/useSegmentTiming.js +65 -0
- package/dist/index.js +34 -0
- package/dist/lib/browser.js +35 -0
- package/dist/lib/facet.js +92 -0
- package/dist/lib/system-messages.js +101 -0
- package/dist/lib/theme/atoms.js +646 -0
- package/dist/lib/theme/atoms.types.js +6 -0
- package/dist/lib/theme/index.js +35 -0
- package/dist/lib/theme/theme.js +256 -0
- package/dist/lib/theme/tokens.js +659 -0
- package/dist/lib/utils.js +105 -0
- package/dist/livestream-provider/index.js +30 -0
- package/dist/livestream-provider/websocket.js +45 -0
- package/dist/livestream-store/chat.js +308 -0
- package/dist/livestream-store/context.js +5 -0
- package/dist/livestream-store/index.js +7 -0
- package/dist/livestream-store/livestream-state.js +2 -0
- package/dist/livestream-store/livestream-store.js +58 -0
- package/dist/livestream-store/problems.js +76 -0
- package/dist/livestream-store/stream-key.js +88 -0
- package/dist/livestream-store/websocket-consumer.js +94 -0
- package/dist/player-store/context.js +5 -0
- package/dist/player-store/index.js +9 -0
- package/dist/player-store/player-provider.js +58 -0
- package/dist/player-store/player-state.js +25 -0
- package/dist/player-store/player-store.js +201 -0
- package/dist/player-store/single-player-provider.js +121 -0
- package/dist/streamplace-provider/context.js +5 -0
- package/dist/streamplace-provider/index.js +20 -0
- package/dist/streamplace-provider/poller.js +49 -0
- package/dist/streamplace-provider/xrpc.js +0 -0
- package/dist/streamplace-store/block.js +65 -0
- package/dist/streamplace-store/index.js +6 -0
- package/dist/streamplace-store/stream.js +247 -0
- package/dist/streamplace-store/streamplace-store.js +47 -0
- package/dist/streamplace-store/user.js +52 -0
- package/dist/streamplace-store/xrpc.js +15 -0
- package/dist/ui/index.js +79 -0
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +5 -4
- package/src/components/chat/chat-box.tsx +3 -0
- package/src/components/chat/mod-view.tsx +39 -5
- package/src/components/mobile-player/fullscreen.tsx +2 -0
- package/src/components/mobile-player/ui/autoplay-button.tsx +86 -0
- package/src/components/mobile-player/ui/index.ts +1 -0
- package/src/components/mobile-player/video.tsx +11 -1
- package/src/livestream-store/chat.tsx +22 -0
- package/src/player-store/player-provider.tsx +2 -1
- package/src/player-store/player-state.tsx +6 -0
- package/src/player-store/player-store.tsx +4 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.viewVariants = exports.Center = exports.Column = exports.Row = exports.Overlay = exports.Surface = exports.Container = exports.Card = exports.View = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const class_variance_authority_1 = require("class-variance-authority");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const react_native_1 = require("react-native");
|
|
8
|
+
const atoms_1 = require("../../lib/theme/atoms");
|
|
9
|
+
const theme_1 = require("../../lib/theme/theme");
|
|
10
|
+
// View variants using class-variance-authority pattern
|
|
11
|
+
const viewVariants = (0, class_variance_authority_1.cva)("", {
|
|
12
|
+
variants: {
|
|
13
|
+
variant: {
|
|
14
|
+
default: "default",
|
|
15
|
+
card: "card",
|
|
16
|
+
overlay: "overlay",
|
|
17
|
+
surface: "surface",
|
|
18
|
+
container: "container",
|
|
19
|
+
},
|
|
20
|
+
padding: {
|
|
21
|
+
none: "none",
|
|
22
|
+
xs: "xs",
|
|
23
|
+
sm: "sm",
|
|
24
|
+
md: "md",
|
|
25
|
+
lg: "lg",
|
|
26
|
+
xl: "xl",
|
|
27
|
+
},
|
|
28
|
+
margin: {
|
|
29
|
+
none: "none",
|
|
30
|
+
xs: "xs",
|
|
31
|
+
sm: "sm",
|
|
32
|
+
md: "md",
|
|
33
|
+
lg: "lg",
|
|
34
|
+
xl: "xl",
|
|
35
|
+
},
|
|
36
|
+
direction: {
|
|
37
|
+
row: "row",
|
|
38
|
+
column: "column",
|
|
39
|
+
"row-reverse": "row-reverse",
|
|
40
|
+
"column-reverse": "column-reverse",
|
|
41
|
+
},
|
|
42
|
+
align: {
|
|
43
|
+
start: "start",
|
|
44
|
+
center: "center",
|
|
45
|
+
end: "end",
|
|
46
|
+
stretch: "stretch",
|
|
47
|
+
baseline: "baseline",
|
|
48
|
+
},
|
|
49
|
+
justify: {
|
|
50
|
+
start: "start",
|
|
51
|
+
center: "center",
|
|
52
|
+
end: "end",
|
|
53
|
+
between: "between",
|
|
54
|
+
around: "around",
|
|
55
|
+
evenly: "evenly",
|
|
56
|
+
},
|
|
57
|
+
flex: {
|
|
58
|
+
none: "none",
|
|
59
|
+
auto: "auto",
|
|
60
|
+
initial: "initial",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
defaultVariants: {
|
|
64
|
+
variant: "default",
|
|
65
|
+
padding: "none",
|
|
66
|
+
margin: "none",
|
|
67
|
+
direction: "column",
|
|
68
|
+
align: "stretch",
|
|
69
|
+
justify: "start",
|
|
70
|
+
flex: "none",
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
exports.viewVariants = viewVariants;
|
|
74
|
+
exports.View = (0, react_1.forwardRef)(({ variant = "default", padding = "none", margin = "none", direction = "column", align = "stretch", justify = "start", flex = "none", fullWidth = false, fullHeight = false, centered = false, backgroundColor, borderColor, borderWidth, borderRadius, shadow = false, style, ...props }, ref) => {
|
|
75
|
+
const { theme } = (0, theme_1.useTheme)();
|
|
76
|
+
// Map variant to styles
|
|
77
|
+
const variantStyles = (() => {
|
|
78
|
+
switch (variant) {
|
|
79
|
+
case "card":
|
|
80
|
+
return {
|
|
81
|
+
backgroundColor: theme.colors.card,
|
|
82
|
+
borderRadius: atoms_1.borderRadius.lg,
|
|
83
|
+
shadowColor: "#000",
|
|
84
|
+
shadowOffset: { width: 0, height: 2 },
|
|
85
|
+
shadowOpacity: 0.1,
|
|
86
|
+
shadowRadius: 4,
|
|
87
|
+
elevation: 3,
|
|
88
|
+
};
|
|
89
|
+
case "overlay":
|
|
90
|
+
return {
|
|
91
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
92
|
+
};
|
|
93
|
+
case "surface":
|
|
94
|
+
return {
|
|
95
|
+
backgroundColor: theme.colors.background,
|
|
96
|
+
};
|
|
97
|
+
case "container":
|
|
98
|
+
return {
|
|
99
|
+
backgroundColor: theme.colors.background,
|
|
100
|
+
padding: atoms_1.spacing[4],
|
|
101
|
+
};
|
|
102
|
+
default:
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
// Map padding to numeric values
|
|
107
|
+
const paddingValue = (() => {
|
|
108
|
+
switch (padding) {
|
|
109
|
+
case "xs":
|
|
110
|
+
return atoms_1.spacing[1];
|
|
111
|
+
case "sm":
|
|
112
|
+
return atoms_1.spacing[2];
|
|
113
|
+
case "md":
|
|
114
|
+
return atoms_1.spacing[3];
|
|
115
|
+
case "lg":
|
|
116
|
+
return atoms_1.spacing[4];
|
|
117
|
+
case "xl":
|
|
118
|
+
return atoms_1.spacing[5];
|
|
119
|
+
default:
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
})();
|
|
123
|
+
// Map margin to numeric values
|
|
124
|
+
const marginValue = (() => {
|
|
125
|
+
switch (margin) {
|
|
126
|
+
case "xs":
|
|
127
|
+
return atoms_1.spacing[1];
|
|
128
|
+
case "sm":
|
|
129
|
+
return atoms_1.spacing[2];
|
|
130
|
+
case "md":
|
|
131
|
+
return atoms_1.spacing[3];
|
|
132
|
+
case "lg":
|
|
133
|
+
return atoms_1.spacing[4];
|
|
134
|
+
case "xl":
|
|
135
|
+
return atoms_1.spacing[5];
|
|
136
|
+
default:
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
})();
|
|
140
|
+
// Map flex direction
|
|
141
|
+
const flexDirection = (() => {
|
|
142
|
+
switch (direction) {
|
|
143
|
+
case "row":
|
|
144
|
+
return "row";
|
|
145
|
+
case "column":
|
|
146
|
+
return "column";
|
|
147
|
+
case "row-reverse":
|
|
148
|
+
return "row-reverse";
|
|
149
|
+
case "column-reverse":
|
|
150
|
+
return "column-reverse";
|
|
151
|
+
default:
|
|
152
|
+
return "column";
|
|
153
|
+
}
|
|
154
|
+
})();
|
|
155
|
+
// Map align items
|
|
156
|
+
const alignItems = (() => {
|
|
157
|
+
switch (align) {
|
|
158
|
+
case "start":
|
|
159
|
+
return "flex-start";
|
|
160
|
+
case "center":
|
|
161
|
+
return "center";
|
|
162
|
+
case "end":
|
|
163
|
+
return "flex-end";
|
|
164
|
+
case "stretch":
|
|
165
|
+
return "stretch";
|
|
166
|
+
case "baseline":
|
|
167
|
+
return "baseline";
|
|
168
|
+
default:
|
|
169
|
+
return "stretch";
|
|
170
|
+
}
|
|
171
|
+
})();
|
|
172
|
+
// Map justify content
|
|
173
|
+
const justifyContent = (() => {
|
|
174
|
+
switch (justify) {
|
|
175
|
+
case "start":
|
|
176
|
+
return "flex-start";
|
|
177
|
+
case "center":
|
|
178
|
+
return "center";
|
|
179
|
+
case "end":
|
|
180
|
+
return "flex-end";
|
|
181
|
+
case "between":
|
|
182
|
+
return "space-between";
|
|
183
|
+
case "around":
|
|
184
|
+
return "space-around";
|
|
185
|
+
case "evenly":
|
|
186
|
+
return "space-evenly";
|
|
187
|
+
default:
|
|
188
|
+
return "flex-start";
|
|
189
|
+
}
|
|
190
|
+
})();
|
|
191
|
+
// Map flex value
|
|
192
|
+
const flexValue = (() => {
|
|
193
|
+
if (typeof flex === "number") {
|
|
194
|
+
return flex;
|
|
195
|
+
}
|
|
196
|
+
switch (flex) {
|
|
197
|
+
case "auto":
|
|
198
|
+
return undefined; // auto is default
|
|
199
|
+
case "initial":
|
|
200
|
+
return 0;
|
|
201
|
+
case "none":
|
|
202
|
+
default:
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
})();
|
|
206
|
+
const computedStyle = {
|
|
207
|
+
...variantStyles,
|
|
208
|
+
...(paddingValue !== undefined && { padding: paddingValue }),
|
|
209
|
+
...(marginValue !== undefined && { margin: marginValue }),
|
|
210
|
+
flexDirection,
|
|
211
|
+
alignItems,
|
|
212
|
+
justifyContent,
|
|
213
|
+
...(flexValue !== undefined && { flex: flexValue }),
|
|
214
|
+
...(fullWidth && { width: "100%" }),
|
|
215
|
+
...(fullHeight && { height: "100%" }),
|
|
216
|
+
...(centered && {
|
|
217
|
+
alignItems: "center",
|
|
218
|
+
justifyContent: "center",
|
|
219
|
+
}),
|
|
220
|
+
...(backgroundColor && { backgroundColor }),
|
|
221
|
+
...(borderColor && { borderColor }),
|
|
222
|
+
...(borderWidth !== undefined && { borderWidth }),
|
|
223
|
+
...(borderRadius !== undefined && { borderRadius }),
|
|
224
|
+
...(shadow && {
|
|
225
|
+
shadowColor: "#000",
|
|
226
|
+
shadowOffset: { width: 0, height: 2 },
|
|
227
|
+
shadowOpacity: 0.1,
|
|
228
|
+
shadowRadius: 4,
|
|
229
|
+
elevation: 3,
|
|
230
|
+
}),
|
|
231
|
+
};
|
|
232
|
+
const finalStyle = Array.isArray(style)
|
|
233
|
+
? [computedStyle, ...style]
|
|
234
|
+
: [computedStyle, style];
|
|
235
|
+
return (0, jsx_runtime_1.jsx)(react_native_1.View, { ref: ref, style: finalStyle, ...props });
|
|
236
|
+
});
|
|
237
|
+
exports.View.displayName = "View";
|
|
238
|
+
// Convenience components
|
|
239
|
+
exports.Card = (0, react_1.forwardRef)((props, ref) => (0, jsx_runtime_1.jsx)(exports.View, { ref: ref, variant: "card", ...props }));
|
|
240
|
+
exports.Card.displayName = "Card";
|
|
241
|
+
exports.Container = (0, react_1.forwardRef)((props, ref) => (0, jsx_runtime_1.jsx)(exports.View, { ref: ref, variant: "container", ...props }));
|
|
242
|
+
exports.Container.displayName = "Container";
|
|
243
|
+
exports.Surface = (0, react_1.forwardRef)((props, ref) => (0, jsx_runtime_1.jsx)(exports.View, { ref: ref, variant: "surface", ...props }));
|
|
244
|
+
exports.Surface.displayName = "Surface";
|
|
245
|
+
exports.Overlay = (0, react_1.forwardRef)((props, ref) => (0, jsx_runtime_1.jsx)(exports.View, { ref: ref, variant: "overlay", ...props }));
|
|
246
|
+
exports.Overlay.displayName = "Overlay";
|
|
247
|
+
exports.Row = (0, react_1.forwardRef)((props, ref) => (0, jsx_runtime_1.jsx)(exports.View, { ref: ref, direction: "row", ...props }));
|
|
248
|
+
exports.Row.displayName = "Row";
|
|
249
|
+
exports.Column = (0, react_1.forwardRef)((props, ref) => (0, jsx_runtime_1.jsx)(exports.View, { ref: ref, direction: "column", ...props }));
|
|
250
|
+
exports.Column.displayName = "Column";
|
|
251
|
+
exports.Center = (0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(exports.View, { ref: ref, centered: true, ...props })));
|
|
252
|
+
exports.Center.displayName = "Center";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
// barrel file :)
|
|
5
|
+
tslib_1.__exportStar(require("./useAvatars"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./useCameraToggle"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./useKeyboard"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./useKeyboardSlide"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./useLivestreamInfo"), exports);
|
|
10
|
+
tslib_1.__exportStar(require("./useOuterAndInnerDimensions"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./usePlayerDimensions"), exports);
|
|
12
|
+
tslib_1.__exportStar(require("./usePointerDevice"), exports);
|
|
13
|
+
tslib_1.__exportStar(require("./useSegmentDimensions"), exports);
|
|
14
|
+
tslib_1.__exportStar(require("./useSegmentTiming"), exports);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useAvatars = useAvatars;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const xrpc_1 = require("../streamplace-store/xrpc");
|
|
6
|
+
function useAvatars(dids) {
|
|
7
|
+
let agent = (0, xrpc_1.usePDSAgent)();
|
|
8
|
+
const [profiles, setProfiles] = (0, react_1.useState)({});
|
|
9
|
+
const inFlight = (0, react_1.useRef)(new Set());
|
|
10
|
+
const missingDids = (0, react_1.useMemo)(() => dids.filter((did) => !(did in profiles) && !inFlight.current.has(did)), [dids, profiles]);
|
|
11
|
+
(0, react_1.useEffect)(() => {
|
|
12
|
+
if (missingDids.length === 0 || !agent)
|
|
13
|
+
return;
|
|
14
|
+
const toFetch = missingDids.slice(0, 25);
|
|
15
|
+
toFetch.forEach((did) => inFlight.current.add(did));
|
|
16
|
+
const fetchProfiles = async () => {
|
|
17
|
+
try {
|
|
18
|
+
const result = await agent.getProfiles({ actors: toFetch });
|
|
19
|
+
const newProfiles = {};
|
|
20
|
+
result.data.profiles.forEach((p) => {
|
|
21
|
+
newProfiles[p.did] = p;
|
|
22
|
+
});
|
|
23
|
+
setProfiles((prev) => ({ ...prev, ...newProfiles }));
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
console.error("Failed to fetch profiles", e);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
toFetch.forEach((did) => inFlight.current.delete(did));
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
fetchProfiles();
|
|
33
|
+
}, [missingDids, agent]);
|
|
34
|
+
return profiles;
|
|
35
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
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(url) {
|
|
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
|
+
// Create the livestream record with title and custom url if available
|
|
23
|
+
await createStreamRecord({
|
|
24
|
+
title,
|
|
25
|
+
customUrl: url || null,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error("Error creating livestream:", error);
|
|
31
|
+
throw new Error("Failed to create livestream record");
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
setRecordSubmitted(false);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const toggleGoLive = (keyboardHeight, closeKeyboard) => {
|
|
38
|
+
if (!ingestStarting) {
|
|
39
|
+
// Optionally close keyboard if provided
|
|
40
|
+
if (closeKeyboard)
|
|
41
|
+
closeKeyboard();
|
|
42
|
+
setShowCountdown(true);
|
|
43
|
+
setIngestStarting(true);
|
|
44
|
+
setIngestLive(true);
|
|
45
|
+
// wait ~3 seconds before announcing
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
handleSubmit();
|
|
48
|
+
}, 3000);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
setIngestStarting(false);
|
|
52
|
+
setIngestLive(false);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
ingest,
|
|
57
|
+
profile,
|
|
58
|
+
title,
|
|
59
|
+
setTitle,
|
|
60
|
+
showCountdown,
|
|
61
|
+
setShowCountdown,
|
|
62
|
+
recordSubmitted,
|
|
63
|
+
setRecordSubmitted,
|
|
64
|
+
ingestStarting,
|
|
65
|
+
setIngestStarting,
|
|
66
|
+
handleSubmit,
|
|
67
|
+
toggleGoLive,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
}
|