@streamplace/components 0.6.37 → 1.0.0
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 +8 -34
- package/LICENSE +0 -18
- package/README.md +0 -35
- package/dist/index.js +0 -6
- package/dist/livestream-provider/index.js +0 -20
- package/dist/livestream-provider/websocket.js +0 -41
- package/dist/livestream-store/chat.js +0 -162
- package/dist/livestream-store/context.js +0 -2
- package/dist/livestream-store/index.js +0 -3
- package/dist/livestream-store/livestream-state.js +0 -1
- package/dist/livestream-store/livestream-store.js +0 -39
- package/dist/livestream-store/websocket-consumer.js +0 -55
- package/dist/player-store/context.js +0 -2
- package/dist/player-store/index.js +0 -6
- package/dist/player-store/player-provider.js +0 -53
- package/dist/player-store/player-state.js +0 -22
- package/dist/player-store/player-store.js +0 -146
- package/dist/player-store/single-player-provider.js +0 -109
- package/dist/streamplace-provider/context.js +0 -2
- package/dist/streamplace-provider/index.js +0 -16
- package/dist/streamplace-provider/poller.js +0 -46
- package/dist/streamplace-provider/xrpc.js +0 -0
- package/dist/streamplace-store/index.js +0 -2
- package/dist/streamplace-store/streamplace-store.js +0 -37
- package/dist/streamplace-store/user.js +0 -47
- package/dist/streamplace-store/xrpc.js +0 -12
- 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/src/index.tsx +0 -6
- package/src/livestream-provider/index.tsx +0 -37
- package/src/livestream-provider/websocket.tsx +0 -47
- package/src/livestream-store/chat.tsx +0 -224
- package/src/livestream-store/context.tsx +0 -10
- package/src/livestream-store/index.tsx +0 -3
- package/src/livestream-store/livestream-state.tsx +0 -18
- package/src/livestream-store/livestream-store.tsx +0 -56
- package/src/livestream-store/websocket-consumer.tsx +0 -62
- package/src/player-store/context.tsx +0 -11
- package/src/player-store/index.tsx +0 -6
- package/src/player-store/player-provider.tsx +0 -90
- package/src/player-store/player-state.tsx +0 -159
- package/src/player-store/player-store.tsx +0 -217
- package/src/player-store/single-player-provider.tsx +0 -181
- package/src/streamplace-provider/context.tsx +0 -10
- package/src/streamplace-provider/index.tsx +0 -32
- package/src/streamplace-provider/poller.tsx +0 -55
- package/src/streamplace-provider/xrpc.tsx +0 -0
- package/src/streamplace-store/index.tsx +0 -2
- package/src/streamplace-store/streamplace-store.tsx +0 -89
- package/src/streamplace-store/user.tsx +0 -57
- package/src/streamplace-store/xrpc.tsx +0 -15
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
package/package.json
CHANGED
|
@@ -1,39 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamplace/components",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "src/index.tsx",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/index.d.mjs",
|
|
11
|
-
"default": "./dist/index.mjs"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "package.json",
|
|
14
6
|
"scripts": {
|
|
15
|
-
"
|
|
16
|
-
"postinstall": "pnpm run build",
|
|
17
|
-
"start": "tsc --watch --preserveWatchOutput"
|
|
18
|
-
},
|
|
19
|
-
"keywords": [
|
|
20
|
-
"streamplace"
|
|
21
|
-
],
|
|
22
|
-
"author": "Streamplace",
|
|
23
|
-
"license": "MIT",
|
|
24
|
-
"packageManager": "pnpm@10.11.0",
|
|
25
|
-
"devDependencies": {
|
|
26
|
-
"tsup": "^8.5.0"
|
|
27
|
-
},
|
|
28
|
-
"dependencies": {
|
|
29
|
-
"@atproto/api": "^0.15.7",
|
|
30
|
-
"react-native": "0.76.2",
|
|
31
|
-
"react-use-websocket": "^4.13.0",
|
|
32
|
-
"streamplace": "0.6.37",
|
|
33
|
-
"zustand": "^5.0.5"
|
|
34
|
-
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"react": "*"
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
37
8
|
},
|
|
38
|
-
"
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"packageManager": "pnpm@9.14.4+sha512.c8180b3fbe4e4bca02c94234717896b5529740a6cbadf19fa78254270403ea2f27d4e1d46a08a0f56c89b63dc8ebfd3ee53326da720273794e6200fcf0d184ab"
|
|
39
13
|
}
|
package/LICENSE
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2025 Streamplace.
|
|
2
|
-
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
-
the Software without restriction, including without limitation the rights to
|
|
6
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
7
|
-
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
subject to the following conditions:
|
|
9
|
-
|
|
10
|
-
The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
copies or substantial portions of the Software.
|
|
12
|
-
|
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
15
|
-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
16
|
-
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
17
|
-
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
18
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# @streamplace/components
|
|
2
|
-
|
|
3
|
-
Heavily WIP but looks something like this:
|
|
4
|
-
|
|
5
|
-
```tsx
|
|
6
|
-
import {
|
|
7
|
-
StreamplaceProvider,
|
|
8
|
-
LivestreamProvider,
|
|
9
|
-
} from "@streamplace/components";
|
|
10
|
-
|
|
11
|
-
export function Provider() {
|
|
12
|
-
<StreamplaceProvider url="https://stream.place" oauthSession={userSession}>
|
|
13
|
-
{/* Everything inside of here can access that Streamplace node */}
|
|
14
|
-
|
|
15
|
-
<LivestreamProvider src="example.bsky.social" /* or did:plc:xxxx */>
|
|
16
|
-
{/* Everything in here has an active subscription to the livestream
|
|
17
|
-
context via Websocket; things like chat data and stream title */}
|
|
18
|
-
<App />
|
|
19
|
-
</LivestreamProvider>
|
|
20
|
-
</StreamplaceProvider>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function App() {
|
|
24
|
-
const chat = useChat();
|
|
25
|
-
return (
|
|
26
|
-
<View>
|
|
27
|
-
{chat.map((msg) => (
|
|
28
|
-
<Text>
|
|
29
|
-
@{msg.author.handle}: {msg.record.text}
|
|
30
|
-
</Text>
|
|
31
|
-
))}
|
|
32
|
-
</View>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
```
|
package/dist/index.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useContext, useRef } from "react";
|
|
3
|
-
import { LivestreamContext, makeLivestreamStore } from "../livestream-store";
|
|
4
|
-
import { useLivestreamWebsocket } from "./websocket";
|
|
5
|
-
export function LivestreamProvider({ children, src, }) {
|
|
6
|
-
const context = useContext(LivestreamContext);
|
|
7
|
-
const store = useRef(makeLivestreamStore()).current;
|
|
8
|
-
if (context) {
|
|
9
|
-
// this is ok, there's use cases for having one in another
|
|
10
|
-
// like having a player component that's independently usable
|
|
11
|
-
// but can also be embedded within an entire livestream page
|
|
12
|
-
return _jsx(_Fragment, { children: children });
|
|
13
|
-
}
|
|
14
|
-
window.livestreamStore = store;
|
|
15
|
-
return (_jsx(LivestreamContext.Provider, { value: { store: store }, children: _jsx(LivestreamPoller, { src: src, children: children }) }));
|
|
16
|
-
}
|
|
17
|
-
export function LivestreamPoller({ children, src, }) {
|
|
18
|
-
useLivestreamWebsocket(src);
|
|
19
|
-
return _jsx(_Fragment, { children: children });
|
|
20
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { useRef } from "react";
|
|
2
|
-
import useWebSocket from "react-use-websocket";
|
|
3
|
-
import { useHandleWebsocketMessages } from "../livestream-store";
|
|
4
|
-
import { useUrl } from "../streamplace-store";
|
|
5
|
-
export function useLivestreamWebsocket(src) {
|
|
6
|
-
const url = useUrl();
|
|
7
|
-
const handleWebSocketMessages = useHandleWebsocketMessages();
|
|
8
|
-
let wsUrl = url.replace(/^http\:/, "ws:");
|
|
9
|
-
wsUrl = wsUrl.replace(/^https\:/, "wss:");
|
|
10
|
-
const ref = useRef([]);
|
|
11
|
-
const handle = useRef(null);
|
|
12
|
-
const { readyState } = useWebSocket(`${wsUrl}/api/websocket/${src}`, {
|
|
13
|
-
reconnectInterval: 1000,
|
|
14
|
-
shouldReconnect: () => true,
|
|
15
|
-
onOpen: () => {
|
|
16
|
-
ref.current = [];
|
|
17
|
-
},
|
|
18
|
-
onError: (e) => {
|
|
19
|
-
console.log("onError", e);
|
|
20
|
-
},
|
|
21
|
-
// spamming the redux store with messages causes a zillion re-renders,
|
|
22
|
-
// so we batch them up a bit
|
|
23
|
-
onMessage: (msg) => {
|
|
24
|
-
try {
|
|
25
|
-
const data = JSON.parse(msg.data);
|
|
26
|
-
ref.current.push(data);
|
|
27
|
-
if (handle.current) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
handle.current = setTimeout(() => {
|
|
31
|
-
handleWebSocketMessages(ref.current);
|
|
32
|
-
ref.current = [];
|
|
33
|
-
handle.current = null;
|
|
34
|
-
}, 250);
|
|
35
|
-
}
|
|
36
|
-
catch (e) {
|
|
37
|
-
console.log("onMessage parse error", e);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
}
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { RichText } from "@atproto/api";
|
|
2
|
-
import { isLink, isMention, } from "@atproto/api/dist/client/types/app/bsky/richtext/facet";
|
|
3
|
-
import { useChatProfile, useDID, useHandle } from "../streamplace-store";
|
|
4
|
-
import { usePDSAgent } from "../streamplace-store/xrpc";
|
|
5
|
-
import { getStoreFromContext, useLivestreamStore } from "./livestream-store";
|
|
6
|
-
export const useReplyToMessage = () => useLivestreamStore((state) => state.replyToMessage);
|
|
7
|
-
export const useSetReplyToMessage = () => {
|
|
8
|
-
const store = getStoreFromContext();
|
|
9
|
-
return (message) => {
|
|
10
|
-
store.setState({ replyToMessage: message });
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
export const useCreateChatMessage = () => {
|
|
14
|
-
const pdsAgent = usePDSAgent();
|
|
15
|
-
const store = getStoreFromContext();
|
|
16
|
-
const userDID = useDID();
|
|
17
|
-
const userHandle = useHandle();
|
|
18
|
-
const chatProfile = useChatProfile();
|
|
19
|
-
return async (msg) => {
|
|
20
|
-
if (!pdsAgent || !userDID) {
|
|
21
|
-
throw new Error("No PDS agent or user DID found");
|
|
22
|
-
}
|
|
23
|
-
let state = store.getState();
|
|
24
|
-
const streamerProfile = state.profile;
|
|
25
|
-
if (!streamerProfile) {
|
|
26
|
-
throw new Error("Profile not found");
|
|
27
|
-
}
|
|
28
|
-
const rt = new RichText({ text: msg.text });
|
|
29
|
-
rt.detectFacetsWithoutResolution();
|
|
30
|
-
const record = {
|
|
31
|
-
text: msg.text,
|
|
32
|
-
createdAt: new Date().toISOString(),
|
|
33
|
-
streamer: streamerProfile.did,
|
|
34
|
-
...(msg.reply
|
|
35
|
-
? {
|
|
36
|
-
reply: {
|
|
37
|
-
root: {
|
|
38
|
-
cid: msg.reply.cid,
|
|
39
|
-
uri: msg.reply.uri,
|
|
40
|
-
},
|
|
41
|
-
parent: {
|
|
42
|
-
cid: msg.reply.cid,
|
|
43
|
-
uri: msg.reply.uri,
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
}
|
|
47
|
-
: {}),
|
|
48
|
-
...(rt.facets && rt.facets.length > 0
|
|
49
|
-
? {
|
|
50
|
-
facets: rt.facets.map((facet) => ({
|
|
51
|
-
index: facet.index,
|
|
52
|
-
features: facet.features
|
|
53
|
-
.filter((feature) => feature.$type === "app.bsky.richtext.facet#link" ||
|
|
54
|
-
feature.$type === "app.bsky.richtext.facet#mention")
|
|
55
|
-
.map((feature) => {
|
|
56
|
-
if (isLink(feature)) {
|
|
57
|
-
return {
|
|
58
|
-
$type: "app.bsky.richtext.facet#link",
|
|
59
|
-
uri: feature.uri,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
else if (isMention(feature)) {
|
|
63
|
-
return {
|
|
64
|
-
$type: "app.bsky.richtext.facet#mention",
|
|
65
|
-
did: feature.did,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
throw new Error("invalid code path");
|
|
70
|
-
}
|
|
71
|
-
}),
|
|
72
|
-
})),
|
|
73
|
-
}
|
|
74
|
-
: {}),
|
|
75
|
-
};
|
|
76
|
-
const localChat = {
|
|
77
|
-
uri: `local-${Date.now()}`,
|
|
78
|
-
cid: "",
|
|
79
|
-
author: {
|
|
80
|
-
did: userDID,
|
|
81
|
-
handle: userHandle || userDID,
|
|
82
|
-
},
|
|
83
|
-
record: record,
|
|
84
|
-
indexedAt: new Date().toISOString(),
|
|
85
|
-
chatProfile: chatProfile || undefined,
|
|
86
|
-
};
|
|
87
|
-
state = reduceChat(state, [localChat], []);
|
|
88
|
-
store.setState(state);
|
|
89
|
-
await pdsAgent.com.atproto.repo.createRecord({
|
|
90
|
-
repo: userDID,
|
|
91
|
-
collection: "place.stream.chat.message",
|
|
92
|
-
record,
|
|
93
|
-
});
|
|
94
|
-
};
|
|
95
|
-
};
|
|
96
|
-
const CHAT_LIMIT = 20;
|
|
97
|
-
export const reduceChat = (state, messages, blocks) => {
|
|
98
|
-
state = { ...state };
|
|
99
|
-
let newChat = {
|
|
100
|
-
...state.chatIndex,
|
|
101
|
-
};
|
|
102
|
-
// Add new messages
|
|
103
|
-
for (let message of messages) {
|
|
104
|
-
const date = new Date(message.record.createdAt);
|
|
105
|
-
const key = `${date.getTime()}-${message.uri}`;
|
|
106
|
-
// Remove existing local message matching the server one
|
|
107
|
-
if (!message.uri.startsWith("local-")) {
|
|
108
|
-
const existingLocalMessageKey = Object.keys(newChat).find((k) => {
|
|
109
|
-
const msg = newChat[k];
|
|
110
|
-
return (msg.uri.startsWith("local-") &&
|
|
111
|
-
msg.record.text === message.record.text &&
|
|
112
|
-
msg.author.did === message.author.did);
|
|
113
|
-
});
|
|
114
|
-
if (existingLocalMessageKey) {
|
|
115
|
-
delete newChat[existingLocalMessageKey];
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// Handle reply information for local-first messages
|
|
119
|
-
if (message.record.reply) {
|
|
120
|
-
const reply = message.record.reply;
|
|
121
|
-
const parentUri = reply?.parent?.uri || reply?.root?.uri;
|
|
122
|
-
if (parentUri) {
|
|
123
|
-
// First try to find the parent message in our chat
|
|
124
|
-
const parentMsgKey = Object.keys(newChat).find((k) => newChat[k].uri === parentUri);
|
|
125
|
-
if (parentMsgKey) {
|
|
126
|
-
// Found the parent message, add its info to our message
|
|
127
|
-
const parentMsg = newChat[parentMsgKey];
|
|
128
|
-
message = {
|
|
129
|
-
...message,
|
|
130
|
-
replyTo: {
|
|
131
|
-
cid: parentMsg.cid,
|
|
132
|
-
uri: parentMsg.uri,
|
|
133
|
-
author: parentMsg.author,
|
|
134
|
-
record: parentMsg.record,
|
|
135
|
-
chatProfile: parentMsg.chatProfile,
|
|
136
|
-
indexedAt: parentMsg.indexedAt,
|
|
137
|
-
},
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
newChat[key] = message;
|
|
143
|
-
}
|
|
144
|
-
for (const block of blocks) {
|
|
145
|
-
for (const [k, v] of Object.entries(newChat)) {
|
|
146
|
-
if (v.author.did === block.record.subject) {
|
|
147
|
-
delete newChat[k];
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
let newChatList = Object.values(newChat).sort((a, b) => new Date(a.record.createdAt) > new Date(b.record.createdAt) ? 1 : -1);
|
|
152
|
-
newChatList = newChatList.slice(-CHAT_LIMIT);
|
|
153
|
-
newChat = newChatList.reduce((acc, msg) => {
|
|
154
|
-
acc[msg.uri] = msg;
|
|
155
|
-
return acc;
|
|
156
|
-
}, {});
|
|
157
|
-
return {
|
|
158
|
-
...state,
|
|
159
|
-
chatIndex: newChat,
|
|
160
|
-
chat: newChatList,
|
|
161
|
-
};
|
|
162
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { useContext } from "react";
|
|
2
|
-
import { createStore, useStore } from "zustand";
|
|
3
|
-
import { LivestreamContext } from "./context";
|
|
4
|
-
import { handleWebSocketMessages } from "./websocket-consumer";
|
|
5
|
-
export const makeLivestreamStore = () => {
|
|
6
|
-
return createStore()((set) => ({
|
|
7
|
-
profile: null,
|
|
8
|
-
chatIndex: {},
|
|
9
|
-
chat: [],
|
|
10
|
-
livestream: null,
|
|
11
|
-
viewers: null,
|
|
12
|
-
segment: null,
|
|
13
|
-
renditions: [],
|
|
14
|
-
replyToMessage: null,
|
|
15
|
-
}));
|
|
16
|
-
};
|
|
17
|
-
export function getStoreFromContext() {
|
|
18
|
-
const context = useContext(LivestreamContext);
|
|
19
|
-
if (!context) {
|
|
20
|
-
throw new Error("useLivestreamStore must be used within a LivestreamProvider");
|
|
21
|
-
}
|
|
22
|
-
return context.store;
|
|
23
|
-
}
|
|
24
|
-
export function useLivestreamStore(selector) {
|
|
25
|
-
const store = getStoreFromContext();
|
|
26
|
-
return useStore(store, selector);
|
|
27
|
-
}
|
|
28
|
-
export const useHandleWebsocketMessages = () => {
|
|
29
|
-
const store = getStoreFromContext();
|
|
30
|
-
return (messages) => {
|
|
31
|
-
store.setState((state) => handleWebSocketMessages(state, messages));
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
export const useChat = () => useLivestreamStore((x) => x.chat);
|
|
35
|
-
export const useProfile = () => useLivestreamStore((x) => x.profile);
|
|
36
|
-
export const useViewers = () => useLivestreamStore((x) => x.viewers);
|
|
37
|
-
export const useLivestream = () => useLivestreamStore((x) => x.livestream);
|
|
38
|
-
export const useSegment = () => useLivestreamStore((x) => x.segment);
|
|
39
|
-
export const useRenditions = () => useLivestreamStore((x) => x.renditions);
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { AppBskyActorDefs } from "@atproto/api";
|
|
2
|
-
import { PlaceStreamChatDefs, PlaceStreamDefs, PlaceStreamLivestream, PlaceStreamSegment, } from "streamplace";
|
|
3
|
-
import { reduceChat } from "./chat";
|
|
4
|
-
export const handleWebSocketMessages = (state, messages) => {
|
|
5
|
-
for (const message of messages) {
|
|
6
|
-
if (PlaceStreamLivestream.isLivestreamView(message)) {
|
|
7
|
-
state = {
|
|
8
|
-
...state,
|
|
9
|
-
livestream: message,
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
else if (PlaceStreamLivestream.isViewerCount(message)) {
|
|
13
|
-
state = {
|
|
14
|
-
...state,
|
|
15
|
-
viewers: message.count,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
else if (PlaceStreamChatDefs.isMessageView(message)) {
|
|
19
|
-
// Explicitly map MessageView to MessageViewHydrated
|
|
20
|
-
const hydrated = {
|
|
21
|
-
uri: message.uri,
|
|
22
|
-
cid: message.cid,
|
|
23
|
-
author: message.author,
|
|
24
|
-
record: message.record,
|
|
25
|
-
indexedAt: message.indexedAt,
|
|
26
|
-
chatProfile: message.chatProfile,
|
|
27
|
-
replyTo: message.replyTo,
|
|
28
|
-
};
|
|
29
|
-
state = reduceChat(state, [hydrated], []);
|
|
30
|
-
}
|
|
31
|
-
else if (PlaceStreamSegment.isRecord(message)) {
|
|
32
|
-
state = {
|
|
33
|
-
...state,
|
|
34
|
-
segment: message,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
else if (PlaceStreamDefs.isBlockView(message)) {
|
|
38
|
-
const block = message;
|
|
39
|
-
state = reduceChat(state, [], [block]);
|
|
40
|
-
}
|
|
41
|
-
else if (PlaceStreamDefs.isRenditions(message)) {
|
|
42
|
-
state = {
|
|
43
|
-
...state,
|
|
44
|
-
renditions: message.renditions,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
else if (AppBskyActorDefs.isProfileViewBasic(message)) {
|
|
48
|
-
state = {
|
|
49
|
-
...state,
|
|
50
|
-
profile: message,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return reduceChat(state, [], []);
|
|
55
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useMemo, useState } from "react";
|
|
3
|
-
import { PlayerContext } from "./context";
|
|
4
|
-
import { makePlayerStore } from "./player-store";
|
|
5
|
-
export const PlayerProvider = ({ children, initialPlayers = [], defaultId = Math.random().toString(36).slice(8), }) => {
|
|
6
|
-
const [players, setPlayers] = useState(() => {
|
|
7
|
-
// Initialize with any initial player IDs provided
|
|
8
|
-
const initialPlayerStores = {};
|
|
9
|
-
for (const playerId of initialPlayers) {
|
|
10
|
-
initialPlayerStores[playerId] = makePlayerStore(playerId);
|
|
11
|
-
}
|
|
12
|
-
// Always create at least one player by default
|
|
13
|
-
if (initialPlayers.length === 0) {
|
|
14
|
-
initialPlayerStores[defaultId] = makePlayerStore(defaultId);
|
|
15
|
-
}
|
|
16
|
-
return initialPlayerStores;
|
|
17
|
-
});
|
|
18
|
-
const createPlayer = useCallback((id) => {
|
|
19
|
-
console.log("Creating new player");
|
|
20
|
-
const playerId = id || Math.random().toString(36).slice(8);
|
|
21
|
-
const playerStore = makePlayerStore(playerId);
|
|
22
|
-
setPlayers((prev) => ({
|
|
23
|
-
...prev,
|
|
24
|
-
[playerId]: playerStore,
|
|
25
|
-
}));
|
|
26
|
-
return playerId;
|
|
27
|
-
}, []);
|
|
28
|
-
const removePlayer = useCallback((id) => {
|
|
29
|
-
setPlayers((prev) => {
|
|
30
|
-
// Don't remove the last player
|
|
31
|
-
if (Object.keys(prev).length <= 1) {
|
|
32
|
-
console.warn("Cannot remove the last player");
|
|
33
|
-
return prev;
|
|
34
|
-
}
|
|
35
|
-
const newPlayers = { ...prev };
|
|
36
|
-
delete newPlayers[id];
|
|
37
|
-
return newPlayers;
|
|
38
|
-
});
|
|
39
|
-
}, []);
|
|
40
|
-
const contextValue = useMemo(() => ({
|
|
41
|
-
players,
|
|
42
|
-
createPlayer,
|
|
43
|
-
removePlayer,
|
|
44
|
-
}), [players, createPlayer, removePlayer]);
|
|
45
|
-
return (_jsx(PlayerContext.Provider, { value: contextValue, children: children }));
|
|
46
|
-
};
|
|
47
|
-
// HOC to wrap components that need player context
|
|
48
|
-
export function withPlayerProvider(Component) {
|
|
49
|
-
return function WithPlayerProvider(props) {
|
|
50
|
-
const { initialPlayers, ...componentProps } = props;
|
|
51
|
-
return (_jsx(PlayerProvider, { initialPlayers: initialPlayers, children: _jsx(Component, { ...componentProps }) }));
|
|
52
|
-
};
|
|
53
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export var PlayerProtocol;
|
|
2
|
-
(function (PlayerProtocol) {
|
|
3
|
-
PlayerProtocol["WEBRTC"] = "webrtc";
|
|
4
|
-
PlayerProtocol["HLS"] = "hls";
|
|
5
|
-
PlayerProtocol["PROGRESSIVE_MP4"] = "progressive-mp4";
|
|
6
|
-
PlayerProtocol["PROGRESSIVE_WEBM"] = "progressive-webm";
|
|
7
|
-
})(PlayerProtocol || (PlayerProtocol = {}));
|
|
8
|
-
export var PlayerStatus;
|
|
9
|
-
(function (PlayerStatus) {
|
|
10
|
-
PlayerStatus["START"] = "start";
|
|
11
|
-
PlayerStatus["PLAYING"] = "playing";
|
|
12
|
-
PlayerStatus["STALLED"] = "stalled";
|
|
13
|
-
PlayerStatus["SUSPEND"] = "suspend";
|
|
14
|
-
PlayerStatus["WAITING"] = "waiting";
|
|
15
|
-
PlayerStatus["PAUSE"] = "pause";
|
|
16
|
-
PlayerStatus["MUTE"] = "mute";
|
|
17
|
-
})(PlayerStatus || (PlayerStatus = {}));
|
|
18
|
-
export var IngestMediaSource;
|
|
19
|
-
(function (IngestMediaSource) {
|
|
20
|
-
IngestMediaSource["USER"] = "user";
|
|
21
|
-
IngestMediaSource["DISPLAY"] = "display";
|
|
22
|
-
})(IngestMediaSource || (IngestMediaSource = {}));
|