@streamplace/components 0.0.1 → 0.7.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.
Files changed (169) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +35 -0
  3. package/dist/components/chat/chat-box.js +109 -0
  4. package/dist/components/chat/chat-message.js +76 -0
  5. package/dist/components/chat/chat.js +56 -0
  6. package/dist/components/chat/mention-suggestions.js +39 -0
  7. package/dist/components/chat/mod-view.js +33 -0
  8. package/dist/components/mobile-player/fullscreen.js +69 -0
  9. package/dist/components/mobile-player/fullscreen.native.js +151 -0
  10. package/dist/components/mobile-player/player.js +103 -0
  11. package/dist/components/mobile-player/props.js +1 -0
  12. package/dist/components/mobile-player/shared.js +51 -0
  13. package/dist/components/mobile-player/ui/countdown.js +79 -0
  14. package/dist/components/mobile-player/ui/index.js +5 -0
  15. package/dist/components/mobile-player/ui/input.js +38 -0
  16. package/dist/components/mobile-player/ui/metrics.js +40 -0
  17. package/dist/components/mobile-player/ui/streamer-context-menu.js +4 -0
  18. package/dist/components/mobile-player/ui/viewer-context-menu.js +20 -0
  19. package/dist/components/mobile-player/use-webrtc.js +232 -0
  20. package/dist/components/mobile-player/video.js +375 -0
  21. package/dist/components/mobile-player/video.native.js +238 -0
  22. package/dist/components/mobile-player/webrtc-diagnostics.js +106 -0
  23. package/dist/components/mobile-player/webrtc-primitives.js +25 -0
  24. package/dist/components/mobile-player/webrtc-primitives.native.js +1 -0
  25. package/dist/components/ui/button.js +220 -0
  26. package/dist/components/ui/dialog.js +203 -0
  27. package/dist/components/ui/dropdown.js +148 -0
  28. package/dist/components/ui/icons.js +22 -0
  29. package/dist/components/ui/index.js +22 -0
  30. package/dist/components/ui/input.js +202 -0
  31. package/dist/components/ui/loader.js +7 -0
  32. package/dist/components/ui/primitives/button.js +121 -0
  33. package/dist/components/ui/primitives/input.js +202 -0
  34. package/dist/components/ui/primitives/modal.js +203 -0
  35. package/dist/components/ui/primitives/text.js +286 -0
  36. package/dist/components/ui/resizeable.js +101 -0
  37. package/dist/components/ui/text.js +175 -0
  38. package/dist/components/ui/textarea.js +17 -0
  39. package/dist/components/ui/toast.js +129 -0
  40. package/dist/components/ui/view.js +250 -0
  41. package/dist/hooks/index.js +9 -0
  42. package/dist/hooks/useAvatars.js +32 -0
  43. package/dist/hooks/useCameraToggle.js +9 -0
  44. package/dist/hooks/useKeyboard.js +33 -0
  45. package/dist/hooks/useKeyboardSlide.js +11 -0
  46. package/dist/hooks/useLivestreamInfo.js +62 -0
  47. package/dist/hooks/useOuterAndInnerDimensions.js +27 -0
  48. package/dist/hooks/usePlayerDimensions.js +19 -0
  49. package/dist/hooks/useSegmentTiming.js +62 -0
  50. package/dist/index.js +16 -0
  51. package/dist/lib/facet.js +88 -0
  52. package/dist/lib/theme/atoms.js +620 -0
  53. package/dist/lib/theme/atoms.types.js +5 -0
  54. package/dist/lib/theme/index.js +9 -0
  55. package/dist/lib/theme/theme.js +248 -0
  56. package/dist/lib/theme/tokens.js +383 -0
  57. package/dist/lib/utils.js +94 -0
  58. package/dist/livestream-provider/index.js +25 -0
  59. package/dist/livestream-provider/websocket.js +41 -0
  60. package/dist/livestream-store/chat.js +186 -0
  61. package/dist/livestream-store/context.js +2 -0
  62. package/dist/livestream-store/index.js +4 -0
  63. package/dist/livestream-store/livestream-state.js +1 -0
  64. package/dist/livestream-store/livestream-store.js +42 -0
  65. package/dist/livestream-store/stream-key.js +115 -0
  66. package/dist/livestream-store/websocket-consumer.js +55 -0
  67. package/dist/player-store/context.js +2 -0
  68. package/dist/player-store/index.js +6 -0
  69. package/dist/player-store/player-provider.js +52 -0
  70. package/dist/player-store/player-state.js +22 -0
  71. package/dist/player-store/player-store.js +159 -0
  72. package/dist/player-store/single-player-provider.js +109 -0
  73. package/dist/streamplace-provider/context.js +2 -0
  74. package/dist/streamplace-provider/index.js +16 -0
  75. package/dist/streamplace-provider/poller.js +46 -0
  76. package/dist/streamplace-provider/xrpc.js +0 -0
  77. package/dist/streamplace-store/block.js +23 -0
  78. package/dist/streamplace-store/index.js +3 -0
  79. package/dist/streamplace-store/stream.js +193 -0
  80. package/dist/streamplace-store/streamplace-store.js +37 -0
  81. package/dist/streamplace-store/user.js +47 -0
  82. package/dist/streamplace-store/xrpc.js +12 -0
  83. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  84. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/56540125 +0 -0
  85. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/67b1eb60 +0 -0
  86. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/7c275f90 +0 -0
  87. package/package.json +50 -8
  88. package/src/components/chat/chat-box.tsx +195 -0
  89. package/src/components/chat/chat-message.tsx +192 -0
  90. package/src/components/chat/chat.tsx +128 -0
  91. package/src/components/chat/mention-suggestions.tsx +71 -0
  92. package/src/components/chat/mod-view.tsx +118 -0
  93. package/src/components/mobile-player/fullscreen.native.tsx +193 -0
  94. package/src/components/mobile-player/fullscreen.tsx +79 -0
  95. package/src/components/mobile-player/player.tsx +134 -0
  96. package/src/components/mobile-player/props.tsx +11 -0
  97. package/src/components/mobile-player/shared.tsx +56 -0
  98. package/src/components/mobile-player/ui/countdown.tsx +119 -0
  99. package/src/components/mobile-player/ui/index.ts +5 -0
  100. package/src/components/mobile-player/ui/input.tsx +85 -0
  101. package/src/components/mobile-player/ui/metrics.tsx +69 -0
  102. package/src/components/mobile-player/ui/streamer-context-menu.tsx +3 -0
  103. package/src/components/mobile-player/ui/viewer-context-menu.tsx +70 -0
  104. package/src/components/mobile-player/use-webrtc.tsx +282 -0
  105. package/src/components/mobile-player/video.native.tsx +360 -0
  106. package/src/components/mobile-player/video.tsx +557 -0
  107. package/src/components/mobile-player/webrtc-diagnostics.tsx +149 -0
  108. package/src/components/mobile-player/webrtc-primitives.native.tsx +6 -0
  109. package/src/components/mobile-player/webrtc-primitives.tsx +33 -0
  110. package/src/components/ui/button.tsx +309 -0
  111. package/src/components/ui/dialog.tsx +376 -0
  112. package/src/components/ui/dropdown.tsx +399 -0
  113. package/src/components/ui/icons.tsx +50 -0
  114. package/src/components/ui/index.ts +33 -0
  115. package/src/components/ui/input.tsx +350 -0
  116. package/src/components/ui/loader.tsx +9 -0
  117. package/src/components/ui/primitives/button.tsx +292 -0
  118. package/src/components/ui/primitives/input.tsx +422 -0
  119. package/src/components/ui/primitives/modal.tsx +421 -0
  120. package/src/components/ui/primitives/text.tsx +499 -0
  121. package/src/components/ui/resizeable.tsx +169 -0
  122. package/src/components/ui/text.tsx +330 -0
  123. package/src/components/ui/textarea.tsx +34 -0
  124. package/src/components/ui/toast.tsx +203 -0
  125. package/src/components/ui/view.tsx +344 -0
  126. package/src/hooks/index.ts +9 -0
  127. package/src/hooks/useAvatars.tsx +44 -0
  128. package/src/hooks/useCameraToggle.ts +12 -0
  129. package/src/hooks/useKeyboard.tsx +41 -0
  130. package/src/hooks/useKeyboardSlide.ts +12 -0
  131. package/src/hooks/useLivestreamInfo.ts +67 -0
  132. package/src/hooks/useOuterAndInnerDimensions.tsx +32 -0
  133. package/src/hooks/usePlayerDimensions.ts +23 -0
  134. package/src/hooks/useSegmentTiming.tsx +88 -0
  135. package/src/index.tsx +27 -0
  136. package/src/lib/facet.ts +131 -0
  137. package/src/lib/theme/atoms.ts +760 -0
  138. package/src/lib/theme/atoms.types.ts +258 -0
  139. package/src/lib/theme/index.ts +48 -0
  140. package/src/lib/theme/theme.tsx +436 -0
  141. package/src/lib/theme/tokens.ts +409 -0
  142. package/src/lib/utils.ts +132 -0
  143. package/src/livestream-provider/index.tsx +48 -0
  144. package/src/livestream-provider/websocket.tsx +47 -0
  145. package/src/livestream-store/chat.tsx +261 -0
  146. package/src/livestream-store/context.tsx +10 -0
  147. package/src/livestream-store/index.tsx +4 -0
  148. package/src/livestream-store/livestream-state.tsx +21 -0
  149. package/src/livestream-store/livestream-store.tsx +59 -0
  150. package/src/livestream-store/stream-key.tsx +124 -0
  151. package/src/livestream-store/websocket-consumer.tsx +62 -0
  152. package/src/player-store/context.tsx +11 -0
  153. package/src/player-store/index.tsx +6 -0
  154. package/src/player-store/player-provider.tsx +89 -0
  155. package/src/player-store/player-state.tsx +187 -0
  156. package/src/player-store/player-store.tsx +239 -0
  157. package/src/player-store/single-player-provider.tsx +181 -0
  158. package/src/streamplace-provider/context.tsx +10 -0
  159. package/src/streamplace-provider/index.tsx +32 -0
  160. package/src/streamplace-provider/poller.tsx +55 -0
  161. package/src/streamplace-provider/xrpc.tsx +0 -0
  162. package/src/streamplace-store/block.tsx +29 -0
  163. package/src/streamplace-store/index.tsx +3 -0
  164. package/src/streamplace-store/stream.tsx +262 -0
  165. package/src/streamplace-store/streamplace-store.tsx +89 -0
  166. package/src/streamplace-store/user.tsx +57 -0
  167. package/src/streamplace-store/xrpc.tsx +15 -0
  168. package/tsconfig.json +9 -0
  169. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,421 @@
1
+ import React, { forwardRef } from "react";
2
+ import {
3
+ Dimensions,
4
+ GestureResponderEvent,
5
+ Modal,
6
+ ModalProps,
7
+ Platform,
8
+ ScrollView,
9
+ ScrollViewProps,
10
+ StyleSheet,
11
+ TouchableOpacity,
12
+ TouchableOpacityProps,
13
+ View,
14
+ ViewProps,
15
+ } from "react-native";
16
+
17
+ const { width: screenWidth, height: screenHeight } = Dimensions.get("window");
18
+
19
+ // Base modal primitive interface
20
+ export interface ModalPrimitiveProps extends Omit<ModalProps, "children"> {
21
+ open?: boolean;
22
+ onOpenChange?: (open: boolean) => void;
23
+ children?: React.ReactNode;
24
+ }
25
+
26
+ // Modal root primitive - handles the native Modal component
27
+ export const ModalRoot = forwardRef<View, ModalPrimitiveProps>(
28
+ (
29
+ {
30
+ open = false,
31
+ onOpenChange,
32
+ children,
33
+ onRequestClose,
34
+ animationType = "fade",
35
+ presentationStyle = Platform.OS === "ios" ? "pageSheet" : "fullScreen",
36
+ transparent = true,
37
+ statusBarTranslucent = Platform.OS === "android",
38
+ ...props
39
+ },
40
+ ref,
41
+ ) => {
42
+ const handleRequestClose = React.useCallback(
43
+ (e: any) => {
44
+ if (onOpenChange) {
45
+ onOpenChange(false);
46
+ }
47
+ if (onRequestClose) {
48
+ onRequestClose(e);
49
+ }
50
+ },
51
+ [onOpenChange, onRequestClose],
52
+ );
53
+
54
+ return (
55
+ <Modal
56
+ visible={open}
57
+ onRequestClose={handleRequestClose}
58
+ animationType={animationType}
59
+ presentationStyle={presentationStyle}
60
+ transparent={transparent}
61
+ statusBarTranslucent={statusBarTranslucent}
62
+ {...props}
63
+ >
64
+ <View ref={ref} style={primitiveStyles.container}>
65
+ {children}
66
+ </View>
67
+ </Modal>
68
+ );
69
+ },
70
+ );
71
+
72
+ ModalRoot.displayName = "ModalRoot";
73
+
74
+ // Modal overlay primitive - semi-transparent background
75
+ export interface ModalOverlayProps extends TouchableOpacityProps {
76
+ dismissible?: boolean;
77
+ onDismiss?: () => void;
78
+ }
79
+
80
+ export const ModalOverlay = forwardRef<
81
+ React.ElementRef<typeof TouchableOpacity>,
82
+ ModalOverlayProps
83
+ >(
84
+ (
85
+ {
86
+ dismissible = true,
87
+ onDismiss,
88
+ onPress,
89
+ style,
90
+ children,
91
+ activeOpacity = 1,
92
+ ...props
93
+ },
94
+ ref,
95
+ ) => {
96
+ const handlePress = React.useCallback(
97
+ (event: GestureResponderEvent) => {
98
+ if (dismissible && onDismiss) {
99
+ onDismiss();
100
+ }
101
+ if (onPress) {
102
+ onPress(event);
103
+ }
104
+ },
105
+ [dismissible, onDismiss, onPress],
106
+ );
107
+
108
+ return (
109
+ <TouchableOpacity
110
+ ref={ref}
111
+ style={[primitiveStyles.overlay, style]}
112
+ activeOpacity={activeOpacity}
113
+ onPress={handlePress}
114
+ {...props}
115
+ >
116
+ {children}
117
+ </TouchableOpacity>
118
+ );
119
+ },
120
+ );
121
+
122
+ ModalOverlay.displayName = "ModalOverlay";
123
+
124
+ // Modal content primitive - the actual content container
125
+ export interface ModalContentProps extends ViewProps {
126
+ position?: "center" | "top" | "bottom" | "left" | "right";
127
+ size?: "sm" | "md" | "lg" | "xl" | "full";
128
+ }
129
+
130
+ export const ModalContent = forwardRef<View, ModalContentProps>(
131
+ (
132
+ {
133
+ children,
134
+ position = "center",
135
+ size = "md",
136
+ style,
137
+ onStartShouldSetResponder,
138
+ ...props
139
+ },
140
+ ref,
141
+ ) => {
142
+ // Prevent touches from propagating to overlay
143
+ const handleStartShouldSetResponder = React.useCallback(() => {
144
+ return true;
145
+ }, []);
146
+
147
+ const positionStyle = React.useMemo(() => {
148
+ switch (position) {
149
+ case "top":
150
+ return primitiveStyles.contentTop;
151
+ case "bottom":
152
+ return primitiveStyles.contentBottom;
153
+ case "left":
154
+ return primitiveStyles.contentLeft;
155
+ case "right":
156
+ return primitiveStyles.contentRight;
157
+ case "center":
158
+ default:
159
+ return primitiveStyles.contentCenter;
160
+ }
161
+ }, [position]);
162
+
163
+ const sizeStyle = React.useMemo(() => {
164
+ switch (size) {
165
+ case "sm":
166
+ return primitiveStyles.sizeSm;
167
+ case "lg":
168
+ return primitiveStyles.sizeLg;
169
+ case "xl":
170
+ return primitiveStyles.sizeXl;
171
+ case "full":
172
+ return primitiveStyles.sizeFull;
173
+ case "md":
174
+ default:
175
+ return primitiveStyles.sizeMd;
176
+ }
177
+ }, [size]);
178
+
179
+ return (
180
+ <View
181
+ ref={ref}
182
+ style={[primitiveStyles.content, positionStyle, sizeStyle, style]}
183
+ onStartShouldSetResponder={
184
+ onStartShouldSetResponder || handleStartShouldSetResponder
185
+ }
186
+ {...props}
187
+ >
188
+ {children}
189
+ </View>
190
+ );
191
+ },
192
+ );
193
+
194
+ ModalContent.displayName = "ModalContent";
195
+
196
+ // Modal header primitive
197
+ export interface ModalHeaderProps extends ViewProps {
198
+ withBorder?: boolean;
199
+ }
200
+
201
+ export const ModalHeader = forwardRef<View, ModalHeaderProps>(
202
+ ({ children, withBorder = false, style, ...props }, ref) => {
203
+ return (
204
+ <View
205
+ ref={ref}
206
+ style={[
207
+ primitiveStyles.header,
208
+ withBorder && primitiveStyles.headerBorder,
209
+ style,
210
+ ]}
211
+ {...props}
212
+ >
213
+ {children}
214
+ </View>
215
+ );
216
+ },
217
+ );
218
+
219
+ ModalHeader.displayName = "ModalHeader";
220
+
221
+ // Modal body primitive - scrollable content area
222
+ export interface ModalBodyProps extends ScrollViewProps {
223
+ scrollable?: boolean;
224
+ }
225
+
226
+ export const ModalBody = forwardRef<ScrollView, ModalBodyProps>(
227
+ ({ children, scrollable = true, style, ...props }, ref) => {
228
+ if (!scrollable) {
229
+ return <View style={[primitiveStyles.body, style]}>{children}</View>;
230
+ }
231
+
232
+ return (
233
+ <ScrollView
234
+ ref={ref}
235
+ style={[primitiveStyles.body, style]}
236
+ showsVerticalScrollIndicator={false}
237
+ keyboardShouldPersistTaps="handled"
238
+ {...props}
239
+ >
240
+ {children}
241
+ </ScrollView>
242
+ );
243
+ },
244
+ );
245
+
246
+ ModalBody.displayName = "ModalBody";
247
+
248
+ // Modal footer primitive
249
+ export interface ModalFooterProps extends ViewProps {
250
+ withBorder?: boolean;
251
+ direction?: "row" | "column";
252
+ justify?:
253
+ | "flex-start"
254
+ | "center"
255
+ | "flex-end"
256
+ | "space-between"
257
+ | "space-around";
258
+ }
259
+
260
+ export const ModalFooter = forwardRef<View, ModalFooterProps>(
261
+ (
262
+ {
263
+ children,
264
+ withBorder = false,
265
+ direction = "row",
266
+ justify = "flex-end",
267
+ style,
268
+ ...props
269
+ },
270
+ ref,
271
+ ) => {
272
+ return (
273
+ <View
274
+ ref={ref}
275
+ style={[
276
+ primitiveStyles.footer,
277
+ withBorder && primitiveStyles.footerBorder,
278
+ {
279
+ flexDirection: direction,
280
+ justifyContent: justify,
281
+ },
282
+ style,
283
+ ]}
284
+ {...props}
285
+ >
286
+ {children}
287
+ </View>
288
+ );
289
+ },
290
+ );
291
+
292
+ ModalFooter.displayName = "ModalFooter";
293
+
294
+ // Modal close trigger primitive
295
+ export interface ModalCloseProps extends TouchableOpacityProps {
296
+ onClose?: () => void;
297
+ }
298
+
299
+ export const ModalClose = forwardRef<
300
+ React.ElementRef<typeof TouchableOpacity>,
301
+ ModalCloseProps
302
+ >(({ children, onClose, onPress, ...props }, ref) => {
303
+ const handlePress = React.useCallback(
304
+ (event: GestureResponderEvent) => {
305
+ if (onClose) {
306
+ onClose();
307
+ }
308
+ if (onPress) {
309
+ onPress(event);
310
+ }
311
+ },
312
+ [onClose, onPress],
313
+ );
314
+
315
+ return (
316
+ <TouchableOpacity ref={ref} onPress={handlePress} {...props}>
317
+ {children}
318
+ </TouchableOpacity>
319
+ );
320
+ });
321
+
322
+ ModalClose.displayName = "ModalClose";
323
+
324
+ // Primitive styles (minimal, unstyled)
325
+ const primitiveStyles = StyleSheet.create({
326
+ container: {
327
+ flex: 1,
328
+ },
329
+ overlay: {
330
+ flex: 1,
331
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
332
+ justifyContent: "center",
333
+ alignItems: "center",
334
+ padding: 16,
335
+ },
336
+ content: {
337
+ backgroundColor: "white",
338
+ borderRadius: 8,
339
+ overflow: "hidden",
340
+ },
341
+ contentCenter: {
342
+ alignSelf: "center",
343
+ },
344
+ contentTop: {
345
+ alignSelf: "center",
346
+ marginTop: 0,
347
+ },
348
+ contentBottom: {
349
+ alignSelf: "center",
350
+ marginTop: "auto",
351
+ },
352
+ contentLeft: {
353
+ alignSelf: "flex-start",
354
+ marginRight: "auto",
355
+ },
356
+ contentRight: {
357
+ alignSelf: "flex-end",
358
+ marginLeft: "auto",
359
+ },
360
+ sizeSm: {
361
+ maxWidth: screenWidth * 0.4,
362
+ maxHeight: screenHeight * 0.6,
363
+ },
364
+ sizeMd: {
365
+ maxWidth: screenWidth * 0.6,
366
+ maxHeight: screenHeight * 0.8,
367
+ },
368
+ sizeLg: {
369
+ maxWidth: screenWidth * 0.8,
370
+ maxHeight: screenHeight * 0.9,
371
+ },
372
+ sizeXl: {
373
+ maxWidth: screenWidth * 0.95,
374
+ maxHeight: screenHeight * 0.95,
375
+ },
376
+ sizeFull: {
377
+ width: screenWidth,
378
+ height: screenHeight,
379
+ maxWidth: screenWidth,
380
+ maxHeight: screenHeight,
381
+ borderRadius: 0,
382
+ },
383
+ header: {
384
+ paddingHorizontal: 16,
385
+ paddingVertical: 12,
386
+ flexDirection: "row",
387
+ alignItems: "center",
388
+ justifyContent: "space-between",
389
+ },
390
+ headerBorder: {
391
+ borderBottomWidth: 1,
392
+ borderBottomColor: "#e5e7eb",
393
+ },
394
+ body: {
395
+ flex: 1,
396
+ paddingHorizontal: 16,
397
+ paddingVertical: 12,
398
+ },
399
+ footer: {
400
+ paddingHorizontal: 16,
401
+ paddingVertical: 12,
402
+ flexDirection: "row",
403
+ alignItems: "center",
404
+ gap: 8,
405
+ },
406
+ footerBorder: {
407
+ borderTopWidth: 1,
408
+ borderTopColor: "#e5e7eb",
409
+ },
410
+ });
411
+
412
+ // Export primitive collection
413
+ export const ModalPrimitive = {
414
+ Root: ModalRoot,
415
+ Overlay: ModalOverlay,
416
+ Content: ModalContent,
417
+ Header: ModalHeader,
418
+ Body: ModalBody,
419
+ Footer: ModalFooter,
420
+ Close: ModalClose,
421
+ };