@streamplace/components 0.7.3 → 0.7.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.
Files changed (85) hide show
  1. package/dist/components/chat/chat-box.js +212 -24
  2. package/dist/components/chat/chat-message.js +5 -5
  3. package/dist/components/chat/chat.js +83 -5
  4. package/dist/components/chat/emoji-suggestions.js +35 -0
  5. package/dist/components/chat/mod-view.js +59 -8
  6. package/dist/components/chat/system-message.js +19 -0
  7. package/dist/components/icons/bluesky-icon.js +9 -0
  8. package/dist/components/keep-awake.js +7 -0
  9. package/dist/components/keep-awake.native.js +16 -0
  10. package/dist/components/mobile-player/fullscreen.js +2 -1
  11. package/dist/components/mobile-player/fullscreen.native.js +3 -3
  12. package/dist/components/mobile-player/player.js +15 -30
  13. package/dist/components/mobile-player/ui/index.js +2 -1
  14. package/dist/components/mobile-player/ui/report-modal.js +90 -0
  15. package/dist/components/mobile-player/ui/{loading.js → streamer-loading-overlay.js} +1 -1
  16. package/dist/components/mobile-player/ui/viewer-context-menu.js +20 -1
  17. package/dist/components/mobile-player/ui/viewer-loading-overlay.js +49 -0
  18. package/dist/components/mobile-player/use-webrtc.js +7 -1
  19. package/dist/components/mobile-player/video-retry.js +29 -0
  20. package/dist/components/mobile-player/video.js +84 -9
  21. package/dist/components/mobile-player/video.native.js +24 -10
  22. package/dist/components/share/sharesheet.js +91 -0
  23. package/dist/components/ui/dialog.js +1 -1
  24. package/dist/components/ui/dropdown.js +6 -6
  25. package/dist/components/ui/index.js +2 -0
  26. package/dist/components/ui/primitives/modal.js +0 -1
  27. package/dist/components/ui/slider.js +5 -0
  28. package/dist/hooks/index.js +1 -0
  29. package/dist/hooks/usePointerDevice.js +71 -0
  30. package/dist/index.js +10 -3
  31. package/dist/lib/system-messages.js +101 -0
  32. package/dist/livestream-store/chat.js +111 -18
  33. package/dist/livestream-store/livestream-store.js +3 -0
  34. package/dist/livestream-store/problems.js +76 -0
  35. package/dist/livestream-store/websocket-consumer.js +39 -4
  36. package/dist/player-store/player-store.js +30 -4
  37. package/dist/streamplace-store/block.js +51 -12
  38. package/dist/ui/index.js +79 -0
  39. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  40. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/56540125 +0 -0
  41. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/67b1eb60 +0 -0
  42. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/7c275f90 +0 -0
  43. package/package.json +6 -2
  44. package/src/components/chat/chat-box.tsx +295 -25
  45. package/src/components/chat/chat-message.tsx +6 -7
  46. package/src/components/chat/chat.tsx +192 -41
  47. package/src/components/chat/emoji-suggestions.tsx +94 -0
  48. package/src/components/chat/mod-view.tsx +119 -40
  49. package/src/components/chat/system-message.tsx +38 -0
  50. package/src/components/icons/bluesky-icon.tsx +9 -0
  51. package/src/components/keep-awake.native.tsx +13 -0
  52. package/src/components/keep-awake.tsx +3 -0
  53. package/src/components/mobile-player/fullscreen.native.tsx +12 -3
  54. package/src/components/mobile-player/fullscreen.tsx +10 -3
  55. package/src/components/mobile-player/player.tsx +28 -36
  56. package/src/components/mobile-player/props.tsx +1 -0
  57. package/src/components/mobile-player/ui/index.ts +2 -1
  58. package/src/components/mobile-player/ui/report-modal.tsx +195 -0
  59. package/src/components/mobile-player/ui/{loading.tsx → streamer-loading-overlay.tsx} +1 -1
  60. package/src/components/mobile-player/ui/viewer-context-menu.tsx +31 -3
  61. package/src/components/mobile-player/ui/viewer-loading-overlay.tsx +66 -0
  62. package/src/components/mobile-player/use-webrtc.tsx +10 -2
  63. package/src/components/mobile-player/video-retry.tsx +28 -0
  64. package/src/components/mobile-player/video.native.tsx +24 -10
  65. package/src/components/mobile-player/video.tsx +100 -21
  66. package/src/components/share/sharesheet.tsx +185 -0
  67. package/src/components/ui/dialog.tsx +1 -1
  68. package/src/components/ui/dropdown.tsx +13 -13
  69. package/src/components/ui/index.ts +2 -0
  70. package/src/components/ui/primitives/modal.tsx +0 -1
  71. package/src/components/ui/slider.tsx +1 -0
  72. package/src/hooks/index.ts +1 -0
  73. package/src/hooks/usePointerDevice.ts +89 -0
  74. package/src/index.tsx +11 -2
  75. package/src/lib/system-messages.ts +135 -0
  76. package/src/livestream-store/chat.tsx +145 -17
  77. package/src/livestream-store/livestream-state.tsx +10 -0
  78. package/src/livestream-store/livestream-store.tsx +3 -0
  79. package/src/livestream-store/problems.tsx +96 -0
  80. package/src/livestream-store/websocket-consumer.tsx +44 -4
  81. package/src/player-store/player-state.tsx +21 -4
  82. package/src/player-store/player-store.tsx +38 -5
  83. package/src/streamplace-store/block.tsx +55 -13
  84. package/src/ui/index.ts +86 -0
  85. package/tsconfig.tsbuildinfo +1 -1
@@ -1,6 +1,8 @@
1
- import { useContext } from "react";
1
+ import { ComAtprotoModerationCreateReport } from "@atproto/api";
2
+ import { useContext, useEffect, useState } from "react";
2
3
  import { ChatMessageViewHydrated } from "streamplace";
3
4
  import { createStore, StoreApi, useStore } from "zustand";
5
+ import { useLivestreamStore } from "../livestream-store";
4
6
  import { PlayerContext } from "./context";
5
7
  import {
6
8
  IngestMediaSource,
@@ -68,9 +70,6 @@ export const makePlayerStore = (id?: string): StoreApi<PlayerState> => {
68
70
  playTime: 0,
69
71
  setPlayTime: (playTime: number) => set(() => ({ playTime })),
70
72
 
71
- offline: false,
72
- setOffline: (offline: boolean) => set(() => ({ offline })),
73
-
74
73
  videoRef: undefined,
75
74
  setVideoRef: (
76
75
  videoRef:
@@ -114,6 +113,10 @@ export const makePlayerStore = (id?: string): StoreApi<PlayerState> => {
114
113
  ingestLive: false,
115
114
  setIngestLive: (ingestLive: boolean) => set(() => ({ ingestLive })),
116
115
 
116
+ reportingURL: null,
117
+ setReportingURL: (reportingURL: string | null) =>
118
+ set(() => ({ reportingURL })),
119
+
117
120
  playerEvent: async (
118
121
  url: string,
119
122
  time: string,
@@ -131,7 +134,8 @@ export const makePlayerStore = (id?: string): StoreApi<PlayerState> => {
131
134
  };
132
135
  try {
133
136
  // fetch url from sp provider
134
- fetch(`${url}/api/player-event`, {
137
+ const reportingURL = x.reportingURL ?? `${url}/api/player-event`;
138
+ fetch(reportingURL, {
135
139
  method: "POST",
136
140
  body: JSON.stringify(data),
137
141
  });
@@ -168,6 +172,15 @@ export const makePlayerStore = (id?: string): StoreApi<PlayerState> => {
168
172
  modMessage: null,
169
173
  setModMessage: (modMessage: ChatMessageViewHydrated | null) =>
170
174
  set(() => ({ modMessage })),
175
+
176
+ reportModalOpen: false,
177
+ setReportModalOpen: (reportModalOpen: boolean) =>
178
+ set(() => ({ reportModalOpen })),
179
+
180
+ reportSubject: null,
181
+ setReportSubject: (
182
+ subject: ComAtprotoModerationCreateReport.InputSchema["subject"] | null,
183
+ ) => set(() => ({ reportSubject: subject })),
171
184
  }));
172
185
  };
173
186
 
@@ -242,3 +255,23 @@ export const intoPlayerProtocol = (protocol: string): PlayerProtocol => {
242
255
  return PlayerProtocol.WEBRTC;
243
256
  }
244
257
  };
258
+
259
+ // returns true if the livestream has been offline for more than 10 seconds and we're not playing
260
+ export const useOffline = () => {
261
+ const status = usePlayerStore((x) => x.status);
262
+ const segment = useLivestreamStore((x) => x.segment);
263
+ const [now, setNow] = useState(Date.now());
264
+ useEffect(() => {
265
+ const interval = setInterval(() => {
266
+ setNow(Date.now());
267
+ }, 500);
268
+ return () => clearInterval(interval);
269
+ }, []);
270
+ if (status === PlayerStatus.PLAYING) {
271
+ return false;
272
+ }
273
+ if (!segment?.startTime) {
274
+ return false;
275
+ }
276
+ return now - Date.parse(segment.startTime) > 10000;
277
+ };
@@ -1,10 +1,12 @@
1
1
  import { AppBskyGraphBlock } from "@atproto/api";
2
+ import { useState } from "react";
2
3
  import { usePDSAgent } from "./xrpc";
3
4
 
4
5
  export function useCreateBlockRecord() {
5
6
  let agent = usePDSAgent();
7
+ const [isLoading, setIsLoading] = useState(false);
6
8
 
7
- return async (subjectDID: string) => {
9
+ const createBlock = async (subjectDID: string) => {
8
10
  if (!agent) {
9
11
  throw new Error("No PDS agent found");
10
12
  }
@@ -13,17 +15,57 @@ export function useCreateBlockRecord() {
13
15
  throw new Error("No user DID found, assuming not logged in");
14
16
  }
15
17
 
16
- const record: AppBskyGraphBlock.Record = {
17
- $type: "app.bsky.graph.block",
18
- subject: subjectDID,
19
- createdAt: new Date().toISOString(),
20
- };
21
- return await agent.com.atproto.repo.createRecord({
22
- repo: agent.did,
23
- collection: "app.bsky.graph.block",
24
- record,
25
- });
26
-
27
- return record;
18
+ setIsLoading(true);
19
+ try {
20
+ const record: AppBskyGraphBlock.Record = {
21
+ $type: "app.bsky.graph.block",
22
+ subject: subjectDID,
23
+ createdAt: new Date().toISOString(),
24
+ };
25
+ const result = await agent.com.atproto.repo.createRecord({
26
+ repo: agent.did,
27
+ collection: "app.bsky.graph.block",
28
+ record,
29
+ });
30
+ return result;
31
+ } finally {
32
+ setIsLoading(false);
33
+ }
34
+ };
35
+
36
+ return { createBlock, isLoading };
37
+ }
38
+
39
+ export function useCreateHideChatRecord() {
40
+ let agent = usePDSAgent();
41
+ const [isLoading, setIsLoading] = useState(false);
42
+
43
+ const createHideChat = async (chatMessageUri: string) => {
44
+ if (!agent) {
45
+ throw new Error("No PDS agent found");
46
+ }
47
+
48
+ if (!agent.did) {
49
+ throw new Error("No user DID found, assuming not logged in");
50
+ }
51
+
52
+ setIsLoading(true);
53
+ try {
54
+ const record = {
55
+ $type: "place.stream.chat.gate",
56
+ hiddenMessage: chatMessageUri,
57
+ };
58
+
59
+ const result = await agent.com.atproto.repo.createRecord({
60
+ repo: agent.did,
61
+ collection: "place.stream.chat.gate",
62
+ record,
63
+ });
64
+ return result;
65
+ } finally {
66
+ setIsLoading(false);
67
+ }
28
68
  };
69
+
70
+ return { createHideChat, isLoading };
29
71
  }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @streamplace/components/ui - Streamplace ZeroCSS
3
+ *
4
+ * Clean export path for ZeroCSS styling utilities, design tokens, and atomic styles.
5
+ * ZeroCSS provides a zero-config, atomic styling system optimized for React Native.
6
+ */
7
+
8
+ // Export the most commonly used ZeroCSS utilities
9
+ export {
10
+ // Core atoms object
11
+ atoms,
12
+ // Common shorthand utilities
13
+ bg,
14
+ // Border utilities
15
+ borders,
16
+ bottom,
17
+ // Flex utilities
18
+ flex,
19
+ // Gap utilities (React Native 0.71+)
20
+ gap,
21
+ h,
22
+ // Layout utilities
23
+ layout,
24
+ left,
25
+ m,
26
+ mb,
27
+ ml,
28
+ mr,
29
+ mt,
30
+ mx,
31
+ my,
32
+ p,
33
+ pb,
34
+ pl,
35
+ // Position utilities
36
+ position,
37
+ pr,
38
+ pt,
39
+ px,
40
+ py,
41
+ r,
42
+ right,
43
+ text,
44
+ top,
45
+ w,
46
+ } from "../lib/theme/atoms";
47
+
48
+ // Export ZeroCSS design tokens
49
+ export {
50
+ borderRadius,
51
+ breakpoints,
52
+ colors,
53
+ shadows,
54
+ spacing,
55
+ typography,
56
+ } from "../lib/theme/tokens";
57
+
58
+ // Export ZeroCSS utility functions
59
+ export {
60
+ debounce,
61
+ mergeStyles,
62
+ platformStyle,
63
+ responsiveValue,
64
+ } from "../lib/utils";
65
+
66
+ // Export ZeroCSS theme system
67
+ export {
68
+ ThemeProvider,
69
+ createThemeColors,
70
+ createThemeIcons,
71
+ createThemeStyles,
72
+ createThemedStyles,
73
+ darkTheme,
74
+ lightTheme,
75
+ usePlatformTypography,
76
+ useTheme,
77
+ type Theme,
78
+ type ThemeIcons,
79
+ type ThemeStyles,
80
+ } from "../lib/theme/theme";
81
+
82
+ // Namespace exports for power users
83
+ export * as theme from "../lib/theme";
84
+ export * as atomsNS from "../lib/theme/atoms";
85
+ export * as tokens from "../lib/theme/tokens";
86
+ export * as utils from "../lib/utils";