@streamplace/components 0.9.15 → 0.10.7
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/components/chat/badge.d.ts.map +1 -1
- package/dist/components/chat/badge.js +4 -2
- package/dist/components/chat/badge.js.map +1 -1
- package/dist/components/chat/chat-box.d.ts +2 -1
- package/dist/components/chat/chat-box.d.ts.map +1 -1
- package/dist/components/chat/chat-box.js +1 -1
- package/dist/components/chat/chat-box.js.map +1 -1
- package/dist/components/chat/chat-message.d.ts.map +1 -1
- package/dist/components/chat/chat-message.js +3 -3
- package/dist/components/chat/chat-message.js.map +1 -1
- package/dist/components/chat/chat.d.ts +4 -2
- package/dist/components/chat/chat.d.ts.map +1 -1
- package/dist/components/chat/chat.js +19 -5
- package/dist/components/chat/chat.js.map +1 -1
- package/dist/components/chat/mod-view.d.ts.map +1 -1
- package/dist/components/chat/mod-view.js +31 -6
- package/dist/components/chat/mod-view.js.map +1 -1
- package/dist/components/chat/teleport-modal.d.ts.map +1 -1
- package/dist/components/chat/teleport-modal.js +5 -4
- package/dist/components/chat/teleport-modal.js.map +1 -1
- package/dist/components/chat/user-profile-card.d.ts.map +1 -1
- package/dist/components/chat/user-profile-card.js +11 -8
- package/dist/components/chat/user-profile-card.js.map +1 -1
- package/dist/components/dashboard/moderator-panel.js +7 -1
- package/dist/components/dashboard/moderator-panel.js.map +1 -1
- package/dist/components/error-boundary.d.ts +15 -0
- package/dist/components/error-boundary.d.ts.map +1 -0
- package/dist/components/error-boundary.js +29 -0
- package/dist/components/error-boundary.js.map +1 -0
- package/dist/components/mobile-player/props.d.ts +1 -0
- package/dist/components/mobile-player/props.d.ts.map +1 -1
- package/dist/components/mobile-player/rotation-lock.js +2 -2
- package/dist/components/mobile-player/rotation-lock.js.map +1 -1
- package/dist/components/mobile-player/ui/viewer-context-menu.d.ts.map +1 -1
- package/dist/components/mobile-player/ui/viewer-context-menu.js +3 -2
- package/dist/components/mobile-player/ui/viewer-context-menu.js.map +1 -1
- package/dist/components/mobile-player/ui/viewer-loading-overlay.d.ts.map +1 -1
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js +1 -0
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js.map +1 -1
- package/dist/components/mobile-player/video-async.native.d.ts.map +1 -1
- package/dist/components/mobile-player/video-async.native.js +9 -2
- package/dist/components/mobile-player/video-async.native.js.map +1 -1
- package/dist/components/mobile-player/video.d.ts +3 -3
- package/dist/components/mobile-player/video.d.ts.map +1 -1
- package/dist/components/mobile-player/video.js.map +1 -1
- package/dist/components/stream-notification/pin-notification.d.ts +7 -0
- package/dist/components/stream-notification/pin-notification.d.ts.map +1 -0
- package/dist/components/stream-notification/pin-notification.js +63 -0
- package/dist/components/stream-notification/pin-notification.js.map +1 -0
- package/dist/components/ui/dropdown.d.ts.map +1 -1
- package/dist/components/ui/dropdown.js +3 -2
- package/dist/components/ui/dropdown.js.map +1 -1
- package/dist/components/ui/dropdown.native.d.ts.map +1 -1
- package/dist/components/ui/dropdown.native.js +3 -1
- package/dist/components/ui/dropdown.native.js.map +1 -1
- package/dist/components/ui/icons.js +1 -1
- package/dist/components/ui/icons.js.map +1 -1
- package/dist/components/ui/menu.d.ts +0 -8
- package/dist/components/ui/menu.d.ts.map +1 -1
- package/dist/components/ui/menu.js +1 -35
- package/dist/components/ui/menu.js.map +1 -1
- package/dist/components/ui/primitives/input.d.ts +4 -4
- package/dist/components/ui/primitives/input.d.ts.map +1 -1
- package/dist/components/ui/primitives/input.js +10 -3
- package/dist/components/ui/primitives/input.js.map +1 -1
- package/dist/components/ui/resizeable.d.ts +1 -1
- package/dist/components/ui/resizeable.d.ts.map +1 -1
- package/dist/components/ui/resizeable.js +8 -5
- package/dist/components/ui/resizeable.js.map +1 -1
- package/dist/components/ui/text.d.ts +1 -1
- package/dist/components/ui/toast.js +4 -4
- package/dist/components/ui/toast.js.map +1 -1
- package/dist/context/profile-cache.d.ts.map +1 -1
- package/dist/context/profile-cache.js +2 -1
- package/dist/context/profile-cache.js.map +1 -1
- package/dist/hooks/useSegmentTiming.js +1 -1
- package/dist/hooks/useSegmentTiming.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/facet.js +1 -1
- package/dist/lib/facet.js.map +1 -1
- package/dist/lib/stream-notifications.d.ts +7 -0
- package/dist/lib/stream-notifications.d.ts.map +1 -1
- package/dist/lib/stream-notifications.js +21 -0
- package/dist/lib/stream-notifications.js.map +1 -1
- package/dist/lib/theme/atoms.d.ts +252 -252
- package/dist/lib/theme/theme.js +2 -2
- package/dist/lib/theme/theme.js.map +1 -1
- package/dist/livestream-provider/index.d.ts +1 -0
- package/dist/livestream-provider/index.d.ts.map +1 -1
- package/dist/livestream-provider/index.js +35 -3
- package/dist/livestream-provider/index.js.map +1 -1
- package/dist/livestream-store/chat.d.ts +2 -0
- package/dist/livestream-store/chat.d.ts.map +1 -1
- package/dist/livestream-store/chat.js +80 -1
- package/dist/livestream-store/chat.js.map +1 -1
- package/dist/livestream-store/livestream-state.d.ts +2 -1
- package/dist/livestream-store/livestream-state.d.ts.map +1 -1
- package/dist/livestream-store/livestream-store.d.ts +3 -2
- package/dist/livestream-store/livestream-store.d.ts.map +1 -1
- package/dist/livestream-store/livestream-store.js +4 -1
- package/dist/livestream-store/livestream-store.js.map +1 -1
- package/dist/livestream-store/websocket-consumer.d.ts.map +1 -1
- package/dist/livestream-store/websocket-consumer.js +14 -0
- package/dist/livestream-store/websocket-consumer.js.map +1 -1
- package/dist/streamplace-store/moderation.d.ts +1 -0
- package/dist/streamplace-store/moderation.d.ts.map +1 -1
- package/dist/streamplace-store/moderation.js +1 -0
- package/dist/streamplace-store/moderation.js.map +1 -1
- package/dist/streamplace-store/moderator-management.d.ts +1 -1
- package/dist/streamplace-store/moderator-management.d.ts.map +1 -1
- package/dist/streamplace-store/stream.d.ts +1 -1
- package/dist/streamplace-store/stream.d.ts.map +1 -1
- package/dist/streamplace-store/streamplace-store.d.ts +0 -1
- package/dist/streamplace-store/streamplace-store.d.ts.map +1 -1
- package/dist/streamplace-store/streamplace-store.js +1 -4
- package/dist/streamplace-store/streamplace-store.js.map +1 -1
- package/dist/streamplace-store/user.d.ts +1 -1
- package/dist/streamplace-store/user.d.ts.map +1 -1
- package/dist/streamplace-store/xrpc.js +4 -4
- package/dist/streamplace-store/xrpc.js.map +1 -1
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +19 -18
- package/src/components/chat/badge.tsx +4 -2
- package/src/components/chat/chat-box.tsx +2 -0
- package/src/components/chat/chat-message.tsx +4 -5
- package/src/components/chat/chat.tsx +32 -5
- package/src/components/chat/mod-view.tsx +82 -3
- package/src/components/chat/teleport-modal.tsx +4 -3
- package/src/components/chat/user-profile-card.tsx +20 -8
- package/src/components/dashboard/moderator-panel.tsx +13 -2
- package/src/components/error-boundary.tsx +42 -0
- package/src/components/mobile-player/props.tsx +1 -0
- package/src/components/mobile-player/rotation-lock.tsx +2 -2
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +3 -2
- package/src/components/mobile-player/ui/viewer-loading-overlay.tsx +1 -0
- package/src/components/mobile-player/video-async.native.tsx +8 -1
- package/src/components/mobile-player/video.tsx +7 -5
- package/src/components/stream-notification/pin-notification.tsx +135 -0
- package/src/components/ui/dropdown.native.tsx +5 -1
- package/src/components/ui/dropdown.tsx +3 -2
- package/src/components/ui/icons.tsx +1 -1
- package/src/components/ui/menu.tsx +56 -62
- package/src/components/ui/primitives/input.tsx +18 -9
- package/src/components/ui/resizeable.tsx +11 -6
- package/src/components/ui/toast.tsx +1 -1
- package/src/context/profile-cache.tsx +7 -1
- package/src/hooks/useSegmentTiming.tsx +1 -1
- package/src/index.tsx +2 -0
- package/src/lib/facet.ts +1 -1
- package/src/lib/stream-notifications.ts +28 -0
- package/src/lib/theme/theme.tsx +1 -1
- package/src/livestream-provider/index.tsx +38 -2
- package/src/livestream-store/chat.tsx +92 -0
- package/src/livestream-store/livestream-state.tsx +2 -0
- package/src/livestream-store/livestream-store.tsx +4 -0
- package/src/livestream-store/websocket-consumer.tsx +15 -0
- package/src/streamplace-store/moderation.tsx +2 -0
- package/src/streamplace-store/moderator-management.tsx +1 -1
- package/src/streamplace-store/streamplace-store.tsx +0 -2
- package/src/streamplace-store/xrpc.tsx +1 -1
- package/node-compile-cache/v22.15.0-x64-92db9086-0/37be0eec +0 -0
package/src/index.tsx
CHANGED
package/src/lib/facet.ts
CHANGED
|
@@ -95,7 +95,7 @@ export const segmentize = (
|
|
|
95
95
|
const { byteStart, byteEnd } = facet.index;
|
|
96
96
|
const features = facet.features;
|
|
97
97
|
|
|
98
|
-
if (byteStart > byteEnd || features.length === 0) {
|
|
98
|
+
if (byteStart > byteEnd || !features || features.length === 0) {
|
|
99
99
|
continue;
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { PinnedRecordViewHydrated } from "streamplace";
|
|
2
3
|
import { streamNotification } from "../components/stream-notification";
|
|
4
|
+
import { PinnedCommentNotification } from "../components/stream-notification/pin-notification";
|
|
3
5
|
import { TeleportNotification } from "../components/stream-notification/teleport-notification";
|
|
4
6
|
|
|
5
7
|
export const StreamNotifications = {
|
|
8
|
+
pinnedComment: (params: {
|
|
9
|
+
pinnedComment: PinnedRecordViewHydrated;
|
|
10
|
+
onDismiss?: (reason?: "user" | "auto") => void;
|
|
11
|
+
onUnpin?: () => void;
|
|
12
|
+
}) => {
|
|
13
|
+
streamNotification.show({
|
|
14
|
+
id: "pinned-comment",
|
|
15
|
+
render: (isExiting, onDismiss) => {
|
|
16
|
+
return React.createElement(PinnedCommentNotification, {
|
|
17
|
+
pinnedComment: params.pinnedComment,
|
|
18
|
+
onDismiss: () => onDismiss("user"),
|
|
19
|
+
onUnpin: () => {
|
|
20
|
+
params.onUnpin?.();
|
|
21
|
+
onDismiss("user");
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
duration: 0, // manually dismissed or auto-dismissed by TTL
|
|
26
|
+
onDismiss: params.onDismiss,
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
pinnedCommentDismiss: () => {
|
|
31
|
+
streamNotification.hide("pinned-comment");
|
|
32
|
+
},
|
|
33
|
+
|
|
6
34
|
teleport: (params: {
|
|
7
35
|
targetHandle: string;
|
|
8
36
|
targetDID: string;
|
package/src/lib/theme/theme.tsx
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from "./tokens";
|
|
19
19
|
|
|
20
20
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
|
21
|
-
import { ToastProvider } from "../../components/ui";
|
|
21
|
+
import { ToastProvider } from "../../components/ui/toast";
|
|
22
22
|
|
|
23
23
|
// Import pairify function for generating theme tokens
|
|
24
24
|
function pairify<T extends Record<string, any>>(
|
|
@@ -4,8 +4,11 @@ import { deleteTeleport } from "../lib/slash-commands/teleport";
|
|
|
4
4
|
import { StreamNotifications } from "../lib/stream-notifications";
|
|
5
5
|
import {
|
|
6
6
|
LivestreamContext,
|
|
7
|
+
getStoreFromContext,
|
|
7
8
|
makeLivestreamStore,
|
|
8
9
|
useLivestreamStore,
|
|
10
|
+
usePinnedComment,
|
|
11
|
+
useUnpinChatMessage,
|
|
9
12
|
} from "../livestream-store";
|
|
10
13
|
import { useDID, usePDSAgent } from "../streamplace-store";
|
|
11
14
|
import { useLivestreamWebsocket } from "./websocket";
|
|
@@ -134,6 +137,40 @@ export function TeleportWatcher({
|
|
|
134
137
|
return <></>;
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
export function PinnedCommentWatcher() {
|
|
141
|
+
const pinnedComment = usePinnedComment();
|
|
142
|
+
const streamerDID = useLivestreamStore((state) => state.profile?.did);
|
|
143
|
+
const unpinChatMessage = useUnpinChatMessage();
|
|
144
|
+
const store = getStoreFromContext();
|
|
145
|
+
const prevPinnedRef = useRef<string | null>(null);
|
|
146
|
+
|
|
147
|
+
// Show/hide notification when pinned comment changes
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
const currentUri = pinnedComment?.uri ?? null;
|
|
150
|
+
if (currentUri === prevPinnedRef.current) return;
|
|
151
|
+
prevPinnedRef.current = currentUri;
|
|
152
|
+
|
|
153
|
+
if (pinnedComment) {
|
|
154
|
+
StreamNotifications.pinnedComment({
|
|
155
|
+
pinnedComment,
|
|
156
|
+
onDismiss: () => {
|
|
157
|
+
store.setState({ pinnedComment: null });
|
|
158
|
+
},
|
|
159
|
+
onUnpin: () => {
|
|
160
|
+
if (!streamerDID) return;
|
|
161
|
+
unpinChatMessage(pinnedComment.uri, streamerDID).catch((e) => {
|
|
162
|
+
console.error("Failed to unpin:", e);
|
|
163
|
+
});
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
} else {
|
|
167
|
+
StreamNotifications.pinnedCommentDismiss();
|
|
168
|
+
}
|
|
169
|
+
}, [pinnedComment, streamerDID, unpinChatMessage]);
|
|
170
|
+
|
|
171
|
+
return <></>;
|
|
172
|
+
}
|
|
173
|
+
|
|
137
174
|
export function LivestreamPoller({
|
|
138
175
|
children,
|
|
139
176
|
src,
|
|
@@ -143,12 +180,11 @@ export function LivestreamPoller({
|
|
|
143
180
|
src: string;
|
|
144
181
|
onTeleport?: (targetHandle: string, targetDID: string) => void;
|
|
145
182
|
}) {
|
|
146
|
-
// Websocket watcher is a sibling instead of a parent to avoid
|
|
147
|
-
// re-rendering when the websocket does stuff
|
|
148
183
|
return (
|
|
149
184
|
<>
|
|
150
185
|
<WebsocketWatcher src={src} />
|
|
151
186
|
<TeleportWatcher onTeleport={onTeleport} />
|
|
187
|
+
<PinnedCommentWatcher />
|
|
152
188
|
{children}
|
|
153
189
|
</>
|
|
154
190
|
);
|
|
@@ -437,3 +437,95 @@ export const useReportChatMessage = () => {
|
|
|
437
437
|
};
|
|
438
438
|
|
|
439
439
|
export const reduceChat = reduceChatIncremental;
|
|
440
|
+
|
|
441
|
+
export const usePinChatMessage = () => {
|
|
442
|
+
const agent = usePDSAgent();
|
|
443
|
+
const store = getStoreFromContext();
|
|
444
|
+
|
|
445
|
+
return async (
|
|
446
|
+
messageUri: string,
|
|
447
|
+
streamerDID: string,
|
|
448
|
+
expiresAt?: string,
|
|
449
|
+
) => {
|
|
450
|
+
if (!agent || !agent.did) {
|
|
451
|
+
throw new Error("No PDS agent or user DID found");
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// If streamer, create directly
|
|
455
|
+
if (agent.did === streamerDID) {
|
|
456
|
+
// First delete any existing pinned records
|
|
457
|
+
const listResult = await agent.com.atproto.repo.listRecords({
|
|
458
|
+
repo: streamerDID,
|
|
459
|
+
collection: "place.stream.chat.pinnedRecord",
|
|
460
|
+
});
|
|
461
|
+
for (const rec of listResult.data.records) {
|
|
462
|
+
const rkey = rec.uri.split("/").pop();
|
|
463
|
+
if (rkey) {
|
|
464
|
+
await agent.com.atproto.repo.deleteRecord({
|
|
465
|
+
repo: streamerDID,
|
|
466
|
+
collection: "place.stream.chat.pinnedRecord",
|
|
467
|
+
rkey,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const record = {
|
|
473
|
+
$type: "place.stream.chat.pinnedRecord",
|
|
474
|
+
pinnedMessage: messageUri,
|
|
475
|
+
createdAt: new Date().toISOString(),
|
|
476
|
+
...(expiresAt ? { expiresAt } : {}),
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
const result = await agent.com.atproto.repo.createRecord({
|
|
480
|
+
repo: streamerDID,
|
|
481
|
+
collection: "place.stream.chat.pinnedRecord",
|
|
482
|
+
record,
|
|
483
|
+
});
|
|
484
|
+
return result;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Otherwise, use delegated moderation endpoint
|
|
488
|
+
const result = await agent.place.stream.moderation.createPin({
|
|
489
|
+
streamer: streamerDID,
|
|
490
|
+
messageUri,
|
|
491
|
+
...(expiresAt ? { expiresAt } : {}),
|
|
492
|
+
});
|
|
493
|
+
return result;
|
|
494
|
+
};
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
export const useUnpinChatMessage = () => {
|
|
498
|
+
const agent = usePDSAgent();
|
|
499
|
+
const store = getStoreFromContext();
|
|
500
|
+
|
|
501
|
+
return async (pinUri: string, streamerDID: string) => {
|
|
502
|
+
if (!agent || !agent.did) {
|
|
503
|
+
throw new Error("No PDS agent or user DID found");
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// If streamer, delete directly
|
|
507
|
+
if (agent.did === streamerDID) {
|
|
508
|
+
const rkey = pinUri.split("/").pop();
|
|
509
|
+
if (!rkey) {
|
|
510
|
+
throw new Error("Invalid pin URI");
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
await agent.com.atproto.repo.deleteRecord({
|
|
514
|
+
repo: streamerDID,
|
|
515
|
+
collection: "place.stream.chat.pinnedRecord",
|
|
516
|
+
rkey,
|
|
517
|
+
});
|
|
518
|
+
// Optimistically clear the pinned comment
|
|
519
|
+
store.setState({ pinnedComment: null });
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Otherwise, use delegated moderation endpoint
|
|
524
|
+
await agent.place.stream.moderation.deletePin({
|
|
525
|
+
streamer: streamerDID,
|
|
526
|
+
pinUri,
|
|
527
|
+
});
|
|
528
|
+
// Optimistically clear the pinned comment
|
|
529
|
+
store.setState({ pinnedComment: null });
|
|
530
|
+
};
|
|
531
|
+
};
|
|
@@ -2,6 +2,7 @@ import { AppBskyActorDefs } from "@atproto/api";
|
|
|
2
2
|
import {
|
|
3
3
|
ChatMessageViewHydrated,
|
|
4
4
|
LivestreamViewHydrated,
|
|
5
|
+
PinnedRecordViewHydrated,
|
|
5
6
|
PlaceStreamDefs,
|
|
6
7
|
PlaceStreamLiveTeleport,
|
|
7
8
|
PlaceStreamModerationPermission,
|
|
@@ -28,6 +29,7 @@ export interface LivestreamState {
|
|
|
28
29
|
setActiveTeleportUri: (uri: string | null) => void;
|
|
29
30
|
websocketConnected: boolean;
|
|
30
31
|
hasReceivedSegment: boolean;
|
|
32
|
+
pinnedComment: PinnedRecordViewHydrated | null;
|
|
31
33
|
moderationPermissions: PlaceStreamModerationPermission.Record[];
|
|
32
34
|
setModerationPermissions: (
|
|
33
35
|
permissions: PlaceStreamModerationPermission.Record[],
|
|
@@ -27,6 +27,7 @@ export const makeLivestreamStore = (): StoreApi<LivestreamState> => {
|
|
|
27
27
|
setActiveTeleportUri: (uri) => set({ activeTeleportUri: uri }),
|
|
28
28
|
websocketConnected: false,
|
|
29
29
|
hasReceivedSegment: false,
|
|
30
|
+
pinnedComment: null,
|
|
30
31
|
moderationPermissions: [],
|
|
31
32
|
setModerationPermissions: (perms) => set({ moderationPermissions: perms }),
|
|
32
33
|
localLivestreamURI: null,
|
|
@@ -60,6 +61,9 @@ export const useHandleWebsocketMessages = () => {
|
|
|
60
61
|
|
|
61
62
|
export const useChat = () => useLivestreamStore((x) => x.chat);
|
|
62
63
|
|
|
64
|
+
export const usePinnedComment = () =>
|
|
65
|
+
useLivestreamStore((x) => x.pinnedComment);
|
|
66
|
+
|
|
63
67
|
export const useProfile = () => useLivestreamStore((x) => x.profile);
|
|
64
68
|
|
|
65
69
|
export const useViewers = () => useLivestreamStore((x) => x.viewers);
|
|
@@ -2,6 +2,7 @@ import { AppBskyActorDefs } from "@atproto/api";
|
|
|
2
2
|
import {
|
|
3
3
|
ChatMessageViewHydrated,
|
|
4
4
|
LivestreamViewHydrated,
|
|
5
|
+
PinnedRecordViewHydrated,
|
|
5
6
|
PlaceStreamChatDefs,
|
|
6
7
|
PlaceStreamChatGate,
|
|
7
8
|
PlaceStreamChatMessage,
|
|
@@ -123,6 +124,20 @@ export const handleWebSocketMessages = (
|
|
|
123
124
|
pendingHides: newPendingHides,
|
|
124
125
|
};
|
|
125
126
|
state = reduceChat(state, [], [], [hiddenMessageUri]);
|
|
127
|
+
} else if (PlaceStreamChatDefs.isPinnedRecordView(message)) {
|
|
128
|
+
const pinnedView = message as PinnedRecordViewHydrated;
|
|
129
|
+
state = {
|
|
130
|
+
...state,
|
|
131
|
+
pinnedComment: pinnedView,
|
|
132
|
+
};
|
|
133
|
+
} else if (
|
|
134
|
+
(message as any).$type === "place.stream.chat.pinnedRecord" &&
|
|
135
|
+
(message as any).deleted === true
|
|
136
|
+
) {
|
|
137
|
+
state = {
|
|
138
|
+
...state,
|
|
139
|
+
pinnedComment: null,
|
|
140
|
+
};
|
|
126
141
|
} else if (PlaceStreamLiveTeleport.isRecord(message)) {
|
|
127
142
|
const teleportRecord = message as PlaceStreamLiveTeleport.Record;
|
|
128
143
|
state = {
|
|
@@ -6,6 +6,7 @@ import { usePDSAgent } from "./xrpc";
|
|
|
6
6
|
export interface ModerationPermissions {
|
|
7
7
|
canBan: boolean;
|
|
8
8
|
canHide: boolean;
|
|
9
|
+
canPin: boolean;
|
|
9
10
|
canManageLivestream: boolean;
|
|
10
11
|
isOwner: boolean;
|
|
11
12
|
isLoading: boolean;
|
|
@@ -177,6 +178,7 @@ export function useCanModerate(
|
|
|
177
178
|
return {
|
|
178
179
|
canBan: isOwner || permissions.includes("ban"),
|
|
179
180
|
canHide: isOwner || permissions.includes("hide"),
|
|
181
|
+
canPin: isOwner || permissions.includes("message.pin"),
|
|
180
182
|
canManageLivestream: isOwner || permissions.includes("livestream.manage"),
|
|
181
183
|
isOwner,
|
|
182
184
|
isLoading,
|
|
@@ -81,7 +81,7 @@ export function useListModerators(): ListModeratorsResult {
|
|
|
81
81
|
|
|
82
82
|
interface AddModeratorParams {
|
|
83
83
|
moderatorDID: string;
|
|
84
|
-
permissions: ("ban" | "hide" | "livestream.manage")[];
|
|
84
|
+
permissions: ("ban" | "hide" | "livestream.manage" | "message.pin")[];
|
|
85
85
|
expirationTime?: string; // ISO 8601 datetime string
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import { StreamplaceAgent } from "streamplace";
|
|
3
|
-
import { useStreamplaceStore, useUrl } from "
|
|
3
|
+
import { useStreamplaceStore, useUrl } from "./streamplace-store";
|
|
4
4
|
|
|
5
5
|
export function usePDSAgent(): StreamplaceAgent | null {
|
|
6
6
|
const oauthSession = useStreamplaceStore((state) => state.oauthSession);
|
|
Binary file
|