@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.
Files changed (122) hide show
  1. package/package.json +13 -16
  2. package/src/components/mobile-player/fullscreen.native.tsx +15 -20
  3. package/src/components/mobile-player/fullscreen.tsx +10 -2
  4. package/src/components/mobile-player/player.tsx +7 -1
  5. package/src/components/mobile-player/props.tsx +2 -0
  6. package/src/components/mobile-player/video.native.tsx +28 -11
  7. package/src/components/mobile-player/video.tsx +14 -3
  8. package/src/hooks/useLivestreamInfo.ts +6 -2
  9. package/src/lib/browser.ts +27 -0
  10. package/src/livestream-store/stream-key.tsx +1 -28
  11. package/src/streamplace-store/stream.tsx +51 -13
  12. package/dist/assets/emoji-data.json +0 -19371
  13. package/dist/components/chat/chat-box.js +0 -314
  14. package/dist/components/chat/chat-message.js +0 -87
  15. package/dist/components/chat/chat.js +0 -149
  16. package/dist/components/chat/emoji-suggestions.js +0 -35
  17. package/dist/components/chat/mention-suggestions.js +0 -42
  18. package/dist/components/chat/mod-view.js +0 -94
  19. package/dist/components/chat/system-message.js +0 -19
  20. package/dist/components/dashboard/chat-panel.js +0 -38
  21. package/dist/components/dashboard/header.js +0 -80
  22. package/dist/components/dashboard/index.js +0 -14
  23. package/dist/components/dashboard/information-widget.js +0 -234
  24. package/dist/components/dashboard/mod-actions.js +0 -71
  25. package/dist/components/dashboard/problems.js +0 -74
  26. package/dist/components/icons/bluesky-icon.js +0 -9
  27. package/dist/components/keep-awake.js +0 -7
  28. package/dist/components/keep-awake.native.js +0 -16
  29. package/dist/components/mobile-player/fullscreen.js +0 -74
  30. package/dist/components/mobile-player/fullscreen.native.js +0 -155
  31. package/dist/components/mobile-player/player.js +0 -94
  32. package/dist/components/mobile-player/props.js +0 -2
  33. package/dist/components/mobile-player/shared.js +0 -54
  34. package/dist/components/mobile-player/ui/countdown.js +0 -83
  35. package/dist/components/mobile-player/ui/index.js +0 -11
  36. package/dist/components/mobile-player/ui/input.js +0 -42
  37. package/dist/components/mobile-player/ui/metrics.js +0 -44
  38. package/dist/components/mobile-player/ui/report-modal.js +0 -90
  39. package/dist/components/mobile-player/ui/streamer-context-menu.js +0 -7
  40. package/dist/components/mobile-player/ui/streamer-loading-overlay.js +0 -104
  41. package/dist/components/mobile-player/ui/viewer-context-menu.js +0 -51
  42. package/dist/components/mobile-player/ui/viewer-loading-overlay.js +0 -49
  43. package/dist/components/mobile-player/ui/viewers.js +0 -23
  44. package/dist/components/mobile-player/use-webrtc.js +0 -243
  45. package/dist/components/mobile-player/video-retry.js +0 -29
  46. package/dist/components/mobile-player/video.js +0 -460
  47. package/dist/components/mobile-player/video.native.js +0 -276
  48. package/dist/components/mobile-player/webrtc-diagnostics.js +0 -110
  49. package/dist/components/mobile-player/webrtc-primitives.js +0 -27
  50. package/dist/components/mobile-player/webrtc-primitives.native.js +0 -8
  51. package/dist/components/share/sharesheet.js +0 -91
  52. package/dist/components/ui/button.js +0 -223
  53. package/dist/components/ui/dialog.js +0 -206
  54. package/dist/components/ui/dropdown.js +0 -172
  55. package/dist/components/ui/icons.js +0 -25
  56. package/dist/components/ui/index.js +0 -34
  57. package/dist/components/ui/info-box.js +0 -31
  58. package/dist/components/ui/info-row.js +0 -23
  59. package/dist/components/ui/input.js +0 -205
  60. package/dist/components/ui/loader.js +0 -10
  61. package/dist/components/ui/primitives/button.js +0 -125
  62. package/dist/components/ui/primitives/input.js +0 -206
  63. package/dist/components/ui/primitives/modal.js +0 -206
  64. package/dist/components/ui/primitives/text.js +0 -292
  65. package/dist/components/ui/resizeable.js +0 -121
  66. package/dist/components/ui/slider.js +0 -5
  67. package/dist/components/ui/text.js +0 -177
  68. package/dist/components/ui/textarea.js +0 -19
  69. package/dist/components/ui/toast.js +0 -175
  70. package/dist/components/ui/view.js +0 -252
  71. package/dist/hooks/index.js +0 -14
  72. package/dist/hooks/useAvatars.js +0 -35
  73. package/dist/hooks/useCameraToggle.js +0 -12
  74. package/dist/hooks/useKeyboard.js +0 -36
  75. package/dist/hooks/useKeyboardSlide.js +0 -14
  76. package/dist/hooks/useLivestreamInfo.js +0 -65
  77. package/dist/hooks/useOuterAndInnerDimensions.js +0 -30
  78. package/dist/hooks/usePlayerDimensions.js +0 -22
  79. package/dist/hooks/usePointerDevice.js +0 -71
  80. package/dist/hooks/useSegmentDimensions.js +0 -17
  81. package/dist/hooks/useSegmentTiming.js +0 -65
  82. package/dist/index.js +0 -34
  83. package/dist/lib/facet.js +0 -92
  84. package/dist/lib/system-messages.js +0 -101
  85. package/dist/lib/theme/atoms.js +0 -646
  86. package/dist/lib/theme/atoms.types.js +0 -6
  87. package/dist/lib/theme/index.js +0 -35
  88. package/dist/lib/theme/theme.js +0 -256
  89. package/dist/lib/theme/tokens.js +0 -659
  90. package/dist/lib/utils.js +0 -105
  91. package/dist/livestream-provider/index.js +0 -30
  92. package/dist/livestream-provider/websocket.js +0 -45
  93. package/dist/livestream-store/chat.js +0 -286
  94. package/dist/livestream-store/context.js +0 -5
  95. package/dist/livestream-store/index.js +0 -7
  96. package/dist/livestream-store/livestream-state.js +0 -2
  97. package/dist/livestream-store/livestream-store.js +0 -58
  98. package/dist/livestream-store/problems.js +0 -76
  99. package/dist/livestream-store/stream-key.js +0 -119
  100. package/dist/livestream-store/websocket-consumer.js +0 -94
  101. package/dist/player-store/context.js +0 -5
  102. package/dist/player-store/index.js +0 -9
  103. package/dist/player-store/player-provider.js +0 -57
  104. package/dist/player-store/player-state.js +0 -25
  105. package/dist/player-store/player-store.js +0 -199
  106. package/dist/player-store/single-player-provider.js +0 -121
  107. package/dist/streamplace-provider/context.js +0 -5
  108. package/dist/streamplace-provider/index.js +0 -20
  109. package/dist/streamplace-provider/poller.js +0 -49
  110. package/dist/streamplace-provider/xrpc.js +0 -0
  111. package/dist/streamplace-store/block.js +0 -65
  112. package/dist/streamplace-store/index.js +0 -6
  113. package/dist/streamplace-store/stream.js +0 -218
  114. package/dist/streamplace-store/streamplace-store.js +0 -47
  115. package/dist/streamplace-store/user.js +0 -52
  116. package/dist/streamplace-store/xrpc.js +0 -15
  117. package/dist/ui/index.js +0 -79
  118. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  119. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/56540125 +0 -0
  120. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/67b1eb60 +0 -0
  121. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/7c275f90 +0 -0
  122. package/tsconfig.tsbuildinfo +0 -1
@@ -1,119 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useStreamKey = void 0;
4
- const crypto_1 = require("@atproto/crypto");
5
- const react_1 = require("react");
6
- const react_native_1 = require("react-native");
7
- const accounts_1 = require("viem/accounts");
8
- const xrpc_1 = require("../streamplace-store/xrpc");
9
- const livestream_store_1 = require("./livestream-store");
10
- function getBrowserName(userAgent) {
11
- // The order matters here, and this may report false positives for unlisted browsers.
12
- if (userAgent.includes("Firefox")) {
13
- // "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"
14
- return "Mozilla Firefox";
15
- }
16
- else if (userAgent.includes("SamsungBrowser")) {
17
- // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"
18
- return "Samsung Internet";
19
- }
20
- else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {
21
- // "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"
22
- return "Opera";
23
- }
24
- else if (userAgent.includes("Edge")) {
25
- // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
26
- return "Microsoft Edge (Legacy)";
27
- }
28
- else if (userAgent.includes("Edg")) {
29
- // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"
30
- return "Microsoft Edge (Chromium)";
31
- }
32
- else if (userAgent.includes("Chrome")) {
33
- // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
34
- return "Google Chrome or Chromium";
35
- }
36
- else if (userAgent.includes("Safari")) {
37
- // "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"
38
- return "Apple Safari";
39
- }
40
- return "unknown";
41
- }
42
- const useStreamKey = () => {
43
- const pdsAgent = (0, xrpc_1.usePDSAgent)();
44
- const streamKey = (0, livestream_store_1.useLivestreamStore)((state) => state.streamKey);
45
- const setStreamKey = (0, livestream_store_1.useLivestreamStore)((state) => state.setStreamKey);
46
- const [key, setKey] = (0, react_1.useState)(streamKey ? JSON.parse(streamKey) : null);
47
- const [error, setError] = (0, react_1.useState)(null);
48
- (0, react_1.useEffect)(() => {
49
- if (key)
50
- return; // already have key
51
- const generateKey = async () => {
52
- if (!pdsAgent) {
53
- setError("PDS Agent is not available");
54
- return;
55
- }
56
- let did = pdsAgent.did;
57
- if (!did) {
58
- setError("PDS Agent did is not available (not logged in?)");
59
- return;
60
- }
61
- const keypair = await crypto_1.Secp256k1Keypair.create({ exportable: true });
62
- const exportedKey = await keypair.export();
63
- const didBytes = new TextEncoder().encode(did);
64
- const combinedKey = new Uint8Array([...exportedKey, ...didBytes]);
65
- const multibaseKey = (0, crypto_1.bytesToMultibase)(combinedKey, "base58btc");
66
- const hexKey = Array.from(exportedKey)
67
- .map((b) => b.toString(16).padStart(2, "0"))
68
- .join("");
69
- const account = (0, accounts_1.privateKeyToAccount)(`0x${hexKey}`);
70
- const newKey = {
71
- privateKey: multibaseKey,
72
- did: keypair.did(),
73
- address: account.address.toLowerCase(),
74
- };
75
- let platform = react_native_1.Platform.OS;
76
- if (react_native_1.Platform.OS === "web" &&
77
- typeof window !== "undefined" &&
78
- window.navigator) {
79
- if (window.navigator.userAgent.includes("streamplace-desktop")) {
80
- platform = "Desktop";
81
- }
82
- else {
83
- platform = getBrowserName(window.navigator.userAgent);
84
- if (platform !== "unknown") {
85
- platform = platform;
86
- }
87
- }
88
- }
89
- else if (platform === "android") {
90
- platform = "Android";
91
- }
92
- else if (platform === "ios") {
93
- platform = "iOS";
94
- }
95
- else if (platform === "macos") {
96
- platform = "macOS";
97
- }
98
- else if (platform === "windows") {
99
- platform = "Windows";
100
- }
101
- const record = {
102
- signingKey: keypair.did(),
103
- createdAt: new Date().toISOString(),
104
- createdBy: "Streamplace on " + platform,
105
- };
106
- await pdsAgent.com.atproto.repo.createRecord({
107
- repo: did,
108
- collection: "place.stream.key",
109
- record,
110
- });
111
- setStreamKey(JSON.stringify(newKey));
112
- setKey(newKey);
113
- };
114
- generateKey();
115
- // eslint-disable-next-line react-hooks/exhaustive-deps
116
- }, [key, setStreamKey]);
117
- return { streamKey: key, error };
118
- };
119
- exports.useStreamKey = useStreamKey;
@@ -1,94 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleWebSocketMessages = void 0;
4
- const api_1 = require("@atproto/api");
5
- const streamplace_1 = require("streamplace");
6
- const system_messages_1 = require("../lib/system-messages");
7
- const chat_1 = require("./chat");
8
- const problems_1 = require("./problems");
9
- const MAX_RECENT_SEGMENTS = 10;
10
- const handleWebSocketMessages = (state, messages) => {
11
- for (const message of messages) {
12
- if (streamplace_1.PlaceStreamLivestream.isLivestreamView(message)) {
13
- const newLivestream = message;
14
- const oldLivestream = state.livestream;
15
- // check if this is actually new
16
- if (!oldLivestream || oldLivestream.uri !== newLivestream.uri) {
17
- const streamTitle = newLivestream.record.title || "something cool!";
18
- const systemMessage = system_messages_1.SystemMessages.streamStart(streamTitle);
19
- // set proper times
20
- systemMessage.indexedAt = newLivestream.indexedAt;
21
- systemMessage.record.createdAt = newLivestream.record.createdAt;
22
- state = (0, chat_1.reduceChat)(state, [systemMessage], []);
23
- }
24
- state = {
25
- ...state,
26
- livestream: newLivestream,
27
- };
28
- }
29
- else if (streamplace_1.PlaceStreamLivestream.isViewerCount(message)) {
30
- state = {
31
- ...state,
32
- viewers: message.count,
33
- };
34
- }
35
- else if (streamplace_1.PlaceStreamChatDefs.isMessageView(message)) {
36
- // Explicitly map MessageView to MessageViewHydrated
37
- const hydrated = {
38
- uri: message.uri,
39
- cid: message.cid,
40
- author: message.author,
41
- record: message.record,
42
- indexedAt: message.indexedAt,
43
- chatProfile: message.chatProfile,
44
- replyTo: message.replyTo,
45
- deleted: message.deleted,
46
- };
47
- state = (0, chat_1.reduceChat)(state, [hydrated], [], []);
48
- }
49
- else if (streamplace_1.PlaceStreamSegment.isRecord(message)) {
50
- const newRecentSegments = [...state.recentSegments];
51
- newRecentSegments.unshift(message);
52
- if (newRecentSegments.length > MAX_RECENT_SEGMENTS) {
53
- newRecentSegments.pop();
54
- }
55
- state = {
56
- ...state,
57
- segment: message,
58
- recentSegments: newRecentSegments,
59
- problems: (0, problems_1.findProblems)(newRecentSegments),
60
- };
61
- }
62
- else if (streamplace_1.PlaceStreamDefs.isBlockView(message)) {
63
- const block = message;
64
- state = (0, chat_1.reduceChat)(state, [], [block], []);
65
- }
66
- else if (streamplace_1.PlaceStreamDefs.isRenditions(message)) {
67
- state = {
68
- ...state,
69
- renditions: message.renditions,
70
- };
71
- }
72
- else if (api_1.AppBskyActorDefs.isProfileViewBasic(message)) {
73
- state = {
74
- ...state,
75
- profile: message,
76
- };
77
- }
78
- else if (streamplace_1.PlaceStreamChatGate.isRecord(message)) {
79
- const hideRecord = message;
80
- const hiddenMessageUri = hideRecord.hiddenMessage;
81
- const newPendingHides = [...state.pendingHides];
82
- if (!newPendingHides.includes(hiddenMessageUri)) {
83
- newPendingHides.push(hiddenMessageUri);
84
- }
85
- state = {
86
- ...state,
87
- pendingHides: newPendingHides,
88
- };
89
- state = (0, chat_1.reduceChat)(state, [], [], [hiddenMessageUri]);
90
- }
91
- }
92
- return (0, chat_1.reduceChat)(state, [], [], []);
93
- };
94
- exports.handleWebSocketMessages = handleWebSocketMessages;
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PlayerContext = void 0;
4
- const react_1 = require("react");
5
- exports.PlayerContext = (0, react_1.createContext)(null);
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- // barrel file :)
5
- tslib_1.__exportStar(require("./context"), exports);
6
- tslib_1.__exportStar(require("./player-provider"), exports);
7
- tslib_1.__exportStar(require("./player-state"), exports);
8
- tslib_1.__exportStar(require("./player-store"), exports);
9
- tslib_1.__exportStar(require("./single-player-provider"), exports);
@@ -1,57 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PlayerProvider = void 0;
4
- exports.withPlayerProvider = withPlayerProvider;
5
- const jsx_runtime_1 = require("react/jsx-runtime");
6
- const react_1 = require("react");
7
- const context_1 = require("./context");
8
- const player_store_1 = require("./player-store");
9
- const PlayerProvider = ({ children, initialPlayers = [], defaultId = Math.random().toString(36).slice(8), }) => {
10
- const [players, setPlayers] = (0, react_1.useState)(() => {
11
- // Initialize with any initial player IDs provided
12
- const initialPlayerStores = {};
13
- for (const playerId of initialPlayers) {
14
- initialPlayerStores[playerId] = (0, player_store_1.makePlayerStore)(playerId);
15
- }
16
- // Always create at least one player by default
17
- if (initialPlayers.length === 0) {
18
- initialPlayerStores[defaultId] = (0, player_store_1.makePlayerStore)(defaultId);
19
- }
20
- return initialPlayerStores;
21
- });
22
- const createPlayer = (0, react_1.useCallback)((id) => {
23
- const playerId = id || Math.random().toString(36).slice(8);
24
- const playerStore = (0, player_store_1.makePlayerStore)(playerId);
25
- setPlayers((prev) => ({
26
- ...prev,
27
- [playerId]: playerStore,
28
- }));
29
- return playerId;
30
- }, []);
31
- const removePlayer = (0, react_1.useCallback)((id) => {
32
- setPlayers((prev) => {
33
- // Don't remove the last player
34
- if (Object.keys(prev).length <= 1) {
35
- console.warn("Cannot remove the last player");
36
- return prev;
37
- }
38
- const newPlayers = { ...prev };
39
- delete newPlayers[id];
40
- return newPlayers;
41
- });
42
- }, []);
43
- const contextValue = (0, react_1.useMemo)(() => ({
44
- players,
45
- createPlayer,
46
- removePlayer,
47
- }), [players, createPlayer, removePlayer]);
48
- return ((0, jsx_runtime_1.jsx)(context_1.PlayerContext.Provider, { value: contextValue, children: children }));
49
- };
50
- exports.PlayerProvider = PlayerProvider;
51
- // HOC to wrap components that need player context
52
- function withPlayerProvider(Component) {
53
- return function WithPlayerProvider(props) {
54
- const { initialPlayers, ...componentProps } = props;
55
- return ((0, jsx_runtime_1.jsx)(exports.PlayerProvider, { initialPlayers: initialPlayers, children: (0, jsx_runtime_1.jsx)(Component, { ...componentProps }) }));
56
- };
57
- }
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IngestMediaSource = exports.PlayerStatus = exports.PlayerProtocol = void 0;
4
- var PlayerProtocol;
5
- (function (PlayerProtocol) {
6
- PlayerProtocol["WEBRTC"] = "webrtc";
7
- PlayerProtocol["HLS"] = "hls";
8
- PlayerProtocol["PROGRESSIVE_MP4"] = "progressive-mp4";
9
- PlayerProtocol["PROGRESSIVE_WEBM"] = "progressive-webm";
10
- })(PlayerProtocol || (exports.PlayerProtocol = PlayerProtocol = {}));
11
- var PlayerStatus;
12
- (function (PlayerStatus) {
13
- PlayerStatus["START"] = "start";
14
- PlayerStatus["PLAYING"] = "playing";
15
- PlayerStatus["STALLED"] = "stalled";
16
- PlayerStatus["SUSPEND"] = "suspend";
17
- PlayerStatus["WAITING"] = "waiting";
18
- PlayerStatus["PAUSE"] = "pause";
19
- PlayerStatus["MUTE"] = "mute";
20
- })(PlayerStatus || (exports.PlayerStatus = PlayerStatus = {}));
21
- var IngestMediaSource;
22
- (function (IngestMediaSource) {
23
- IngestMediaSource["USER"] = "user";
24
- IngestMediaSource["DISPLAY"] = "display";
25
- })(IngestMediaSource || (exports.IngestMediaSource = IngestMediaSource = {}));
@@ -1,199 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useOffline = exports.intoPlayerProtocol = exports.usePlayerProtocol = exports.makePlayerStore = void 0;
4
- exports.usePlayerContext = usePlayerContext;
5
- exports.getPlayerStoreById = getPlayerStoreById;
6
- exports.getFirstPlayerID = getFirstPlayerID;
7
- exports.getPlayerStoreFromContext = getPlayerStoreFromContext;
8
- exports.usePlayerStore = usePlayerStore;
9
- const react_1 = require("react");
10
- const zustand_1 = require("zustand");
11
- const livestream_store_1 = require("../livestream-store");
12
- const context_1 = require("./context");
13
- const player_state_1 = require("./player-state");
14
- const makePlayerStore = (id) => {
15
- return (0, zustand_1.createStore)()((set) => ({
16
- id: id || Math.random().toString(36).slice(8),
17
- selectedRendition: "source",
18
- setSelectedRendition: (rendition) => set((state) => ({ ...state, selectedRendition: rendition })),
19
- protocol: player_state_1.PlayerProtocol.WEBRTC,
20
- setProtocol: (protocol) => set((state) => ({ ...state, protocol: protocol })),
21
- src: "",
22
- setSrc: (src) => set(() => ({ src })),
23
- ingestStarting: false,
24
- setIngestStarting: (ingestStarting) => set(() => ({ ingestStarting })),
25
- ingestMediaSource: undefined,
26
- setIngestMediaSource: (ingestMediaSource) => set(() => ({ ingestMediaSource })),
27
- ingestCamera: "user",
28
- setIngestCamera: (ingestCamera) => set(() => ({ ingestCamera })),
29
- ingestConnectionState: null,
30
- setIngestConnectionState: (ingestConnectionState) => set(() => ({ ingestConnectionState })),
31
- ingestAutoStart: false,
32
- setIngestAutoStart: (ingestAutoStart) => set(() => ({ ingestAutoStart })),
33
- ingestStarted: null,
34
- setIngestStarted: (timestamp) => set(() => ({ ingestStarted: timestamp })),
35
- muted: false,
36
- setMuted: (isMuted) => set(() => ({ muted: isMuted, muteWasForced: false })),
37
- volume: 1.0,
38
- setVolume: (volume) => set(() => ({ volume, muteWasForced: false })),
39
- fullscreen: false,
40
- setFullscreen: (isFullscreen) => set(() => ({ fullscreen: isFullscreen })),
41
- status: player_state_1.PlayerStatus.START,
42
- setStatus: (status) => set(() => ({ status })),
43
- playTime: 0,
44
- setPlayTime: (playTime) => set(() => ({ playTime })),
45
- videoRef: undefined,
46
- setVideoRef: (videoRef) => set(() => ({ videoRef })),
47
- pipMode: false,
48
- setPipMode: (pipMode) => set(() => ({ pipMode })),
49
- // Picture-in-Picture action function (set by player component)
50
- pipAction: undefined,
51
- setPipAction: (action) => set(() => ({ pipAction: action })),
52
- // Player element width/height setters for global sync
53
- playerWidth: undefined,
54
- setPlayerWidth: (playerWidth) => set(() => ({ playerWidth })),
55
- playerHeight: undefined,
56
- setPlayerHeight: (playerHeight) => set(() => ({ playerHeight })),
57
- // * Whether mute was forced by the browser or not for autoplay
58
- // * Will get set to 'false' if the user has interacted with the volume
59
- muteWasForced: false,
60
- setMuteWasForced: (muteWasForced) => set(() => ({ muteWasForced })),
61
- embedded: false,
62
- setEmbedded: (embedded) => set(() => ({ embedded })),
63
- showControls: true,
64
- controlsTimeout: undefined,
65
- setShowControls: (showControls) => set({ showControls, controlsTimeout: undefined }),
66
- telemetry: true,
67
- setTelemetry: (telemetry) => set(() => ({ telemetry })),
68
- ingestLive: false,
69
- setIngestLive: (ingestLive) => set(() => ({ ingestLive })),
70
- reportingURL: null,
71
- setReportingURL: (reportingURL) => set(() => ({ reportingURL })),
72
- playerEvent: async (url, time, eventType, meta) => set((x) => {
73
- const data = {
74
- time: time,
75
- playerId: x.id,
76
- eventType: eventType,
77
- meta: {
78
- ...meta,
79
- },
80
- };
81
- try {
82
- // fetch url from sp provider
83
- const reportingURL = x.reportingURL ?? `${url}/api/player-event`;
84
- fetch(reportingURL, {
85
- method: "POST",
86
- body: JSON.stringify(data),
87
- });
88
- }
89
- catch (e) {
90
- console.error("error sending player telemetry", e);
91
- }
92
- return {};
93
- }),
94
- // Clear the controls timeout, if it exists.
95
- // Should be called on player unmount.
96
- clearControlsTimeout: () => set((state) => {
97
- if (state.controlsTimeout) {
98
- clearTimeout(state.controlsTimeout);
99
- }
100
- return { controlsTimeout: undefined };
101
- }),
102
- setUserInteraction: () => set((p) => {
103
- // controls timeout
104
- if (p.controlsTimeout) {
105
- clearTimeout(p.controlsTimeout);
106
- }
107
- let controlsTimeout = setTimeout(() => p.setShowControls(false), 1000);
108
- return { showControls: true, controlsTimeout };
109
- }),
110
- showDebugInfo: false,
111
- setShowDebugInfo: (showDebugInfo) => set(() => ({ showDebugInfo })),
112
- modMessage: null,
113
- setModMessage: (modMessage) => set(() => ({ modMessage })),
114
- reportModalOpen: false,
115
- setReportModalOpen: (reportModalOpen) => set(() => ({ reportModalOpen })),
116
- reportSubject: null,
117
- setReportSubject: (subject) => set(() => ({ reportSubject: subject })),
118
- }));
119
- };
120
- exports.makePlayerStore = makePlayerStore;
121
- function usePlayerContext() {
122
- const context = (0, react_1.useContext)(context_1.PlayerContext);
123
- if (!context) {
124
- throw new Error("usePlayerContext must be used within a PlayerProvider");
125
- }
126
- return context;
127
- }
128
- // Get a specific player store by ID
129
- function getPlayerStoreById(id) {
130
- const { players } = usePlayerContext();
131
- const playerStore = players[id];
132
- if (!playerStore) {
133
- throw new Error(`No player found with ID: ${id}`);
134
- }
135
- return playerStore;
136
- }
137
- // Will get the first player ID in the context
138
- function getFirstPlayerID() {
139
- const { players } = usePlayerContext();
140
- const playerIds = Object.keys(players);
141
- if (playerIds.length === 0) {
142
- throw new Error("No players found in context");
143
- }
144
- return playerIds[0];
145
- }
146
- function getPlayerStoreFromContext() {
147
- console.warn("getPlayerStoreFromContext is deprecated. Use getPlayerStoreById instead.");
148
- const { players } = usePlayerContext();
149
- const playerIds = Object.keys(players);
150
- if (playerIds.length === 0) {
151
- throw new Error("No players found in context");
152
- }
153
- return players[playerIds[0]];
154
- }
155
- // Use a specific player store by ID
156
- // If no ID is provided, it will use the first player in the context
157
- function usePlayerStore(selector, playerId) {
158
- if (!playerId) {
159
- playerId = Object.keys(usePlayerContext().players)[0];
160
- }
161
- const store = getPlayerStoreById(playerId);
162
- return (0, zustand_1.useStore)(store, selector);
163
- }
164
- /* Convenience selectors/hooks */
165
- const usePlayerProtocol = (playerId) => usePlayerStore((x) => [x.protocol, x.setProtocol], playerId);
166
- exports.usePlayerProtocol = usePlayerProtocol;
167
- const intoPlayerProtocol = (protocol) => {
168
- switch (protocol) {
169
- case "hls":
170
- return player_state_1.PlayerProtocol.HLS;
171
- case "progressive-mp4":
172
- return player_state_1.PlayerProtocol.PROGRESSIVE_MP4;
173
- case "progressive-webm":
174
- return player_state_1.PlayerProtocol.PROGRESSIVE_WEBM;
175
- default:
176
- return player_state_1.PlayerProtocol.WEBRTC;
177
- }
178
- };
179
- exports.intoPlayerProtocol = intoPlayerProtocol;
180
- // returns true if the livestream has been offline for more than 10 seconds and we're not playing
181
- const useOffline = () => {
182
- const status = usePlayerStore((x) => x.status);
183
- const segment = (0, livestream_store_1.useLivestreamStore)((x) => x.segment);
184
- const [now, setNow] = (0, react_1.useState)(Date.now());
185
- (0, react_1.useEffect)(() => {
186
- const interval = setInterval(() => {
187
- setNow(Date.now());
188
- }, 500);
189
- return () => clearInterval(interval);
190
- }, []);
191
- if (status === player_state_1.PlayerStatus.PLAYING) {
192
- return false;
193
- }
194
- if (!segment?.startTime) {
195
- return false;
196
- }
197
- return now - Date.parse(segment.startTime) > 10000;
198
- };
199
- exports.useOffline = useOffline;
@@ -1,121 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SinglePlayerProvider = void 0;
4
- exports.useSinglePlayerContext = useSinglePlayerContext;
5
- exports.useCurrentPlayerId = useCurrentPlayerId;
6
- exports.useCurrentPlayerStore = useCurrentPlayerStore;
7
- exports.useCurrentPlayerProtocol = useCurrentPlayerProtocol;
8
- exports.useCurrentPlayerRendition = useCurrentPlayerRendition;
9
- exports.useCurrentPlayerIngest = useCurrentPlayerIngest;
10
- exports.withSinglePlayer = withSinglePlayer;
11
- const tslib_1 = require("tslib");
12
- const jsx_runtime_1 = require("react/jsx-runtime");
13
- const react_1 = tslib_1.__importStar(require("react"));
14
- const zustand_1 = require("zustand");
15
- const player_store_1 = require("../player-store");
16
- const player_state_1 = require("./player-state");
17
- const SinglePlayerContext = (0, react_1.createContext)(null);
18
- /**
19
- * Provider component for a single player that creates a scoped context
20
- * This allows components to access a specific player's state without passing IDs around
21
- */
22
- const SinglePlayerProvider = ({ children, playerId: providedPlayerId, protocol = player_state_1.PlayerProtocol.WEBRTC, rendition = "auto", }) => {
23
- const { players, createPlayer } = (0, player_store_1.usePlayerContext)();
24
- // Create or get a player ID
25
- const playerId = (0, react_1.useMemo)(() => {
26
- // If a player ID is provided and exists, use it
27
- if (providedPlayerId && players[providedPlayerId]) {
28
- return providedPlayerId;
29
- }
30
- // If a player ID is provided but doesn't exist, create it
31
- if (providedPlayerId) {
32
- return createPlayer(providedPlayerId);
33
- }
34
- // Otherwise create a new player
35
- return createPlayer();
36
- }, [providedPlayerId, players, createPlayer]);
37
- // Get the player store
38
- const playerStore = (0, react_1.useMemo)(() => {
39
- return players[playerId];
40
- }, [players, playerId]);
41
- // Set initial protocol and rendition if provided
42
- react_1.default.useEffect(() => {
43
- if (protocol) {
44
- playerStore.setState((state) => ({
45
- ...state,
46
- protocol,
47
- }));
48
- }
49
- if (rendition) {
50
- playerStore.setState((state) => ({
51
- ...state,
52
- selectedRendition: rendition,
53
- }));
54
- }
55
- }, [playerStore, protocol, rendition]);
56
- // Create context value
57
- const contextValue = (0, react_1.useMemo)(() => ({
58
- playerId,
59
- playerStore,
60
- }), [playerId, playerStore]);
61
- return ((0, jsx_runtime_1.jsx)(SinglePlayerContext.Provider, { value: contextValue, children: children }));
62
- };
63
- exports.SinglePlayerProvider = SinglePlayerProvider;
64
- /**
65
- * Hook to access the current single player context
66
- */
67
- function useSinglePlayerContext() {
68
- const context = (0, react_1.useContext)(SinglePlayerContext);
69
- if (!context) {
70
- throw new Error("useSinglePlayerContext must be used within a SinglePlayerProvider");
71
- }
72
- return context;
73
- }
74
- /**
75
- * Hook to access the current player ID from the single player context
76
- */
77
- function useCurrentPlayerId() {
78
- const { playerId } = useSinglePlayerContext();
79
- return playerId;
80
- }
81
- /**
82
- * Hook to access state from the current player without needing to specify the ID
83
- */
84
- function useCurrentPlayerStore(selector) {
85
- const { playerStore } = useSinglePlayerContext();
86
- return (0, zustand_1.useStore)(playerStore, selector);
87
- }
88
- /**
89
- * Hook to get the protocol of the current player
90
- */
91
- function useCurrentPlayerProtocol() {
92
- return useCurrentPlayerStore((state) => [state.protocol, state.setProtocol]);
93
- }
94
- /**
95
- * Hook to get the selected rendition of the current player
96
- */
97
- function useCurrentPlayerRendition() {
98
- return useCurrentPlayerStore((state) => [state.selectedRendition, state.setSelectedRendition]);
99
- }
100
- /**
101
- * Hook to get the ingest state of the current player
102
- */
103
- function useCurrentPlayerIngest() {
104
- return useCurrentPlayerStore((state) => ({
105
- starting: state.ingestStarting,
106
- setStarting: state.setIngestStarting,
107
- connectionState: state.ingestConnectionState,
108
- setConnectionState: state.setIngestConnectionState,
109
- startedTimestamp: state.ingestStarted,
110
- setStartedTimestamp: state.setIngestStarted,
111
- }));
112
- }
113
- /**
114
- * HOC to wrap components with a SinglePlayerProvider
115
- */
116
- function withSinglePlayer(Component) {
117
- return function WithSinglePlayer(props) {
118
- const { playerId, protocol, rendition, ...componentProps } = props;
119
- return ((0, jsx_runtime_1.jsx)(exports.SinglePlayerProvider, { playerId: playerId, protocol: protocol, rendition: rendition, children: (0, jsx_runtime_1.jsx)(Component, { ...componentProps }) }));
120
- };
121
- }
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StreamplaceContext = void 0;
4
- const react_1 = require("react");
5
- exports.StreamplaceContext = (0, react_1.createContext)(null);
@@ -1,20 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StreamplaceProvider = StreamplaceProvider;
4
- const tslib_1 = require("tslib");
5
- const jsx_runtime_1 = require("react/jsx-runtime");
6
- const react_1 = require("react");
7
- const streamplace_store_1 = require("../streamplace-store/streamplace-store");
8
- const context_1 = require("./context");
9
- const poller_1 = tslib_1.__importDefault(require("./poller"));
10
- function StreamplaceProvider({ children, url, oauthSession, }) {
11
- // todo: handle url changes?
12
- const store = (0, react_1.useRef)((0, streamplace_store_1.makeStreamplaceStore)({ url })).current;
13
- (0, react_1.useEffect)(() => {
14
- store.setState({ url });
15
- }, [url]);
16
- (0, react_1.useEffect)(() => {
17
- store.setState({ oauthSession });
18
- }, [oauthSession]);
19
- return ((0, jsx_runtime_1.jsx)(context_1.StreamplaceContext.Provider, { value: { store: store }, children: (0, jsx_runtime_1.jsx)(poller_1.default, { children: children }) }));
20
- }