@streamplace/components 0.7.26 → 0.7.29
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/chat-box.js +2 -2
- package/dist/components/chat/chat.js +1 -1
- package/dist/components/mobile-player/ui/autoplay-button.js +1 -0
- package/dist/components/mobile-player/ui/viewer-context-menu.js +1 -1
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js +2 -2
- package/dist/components/mobile-player/use-webrtc.js +37 -1
- package/dist/components/mobile-player/video.native.js +10 -1
- package/dist/components/ui/button.js +107 -155
- package/dist/components/ui/dialog.js +83 -116
- package/dist/components/ui/dropdown.js +41 -18
- package/dist/components/ui/input.js +53 -128
- package/dist/components/ui/primitives/button.js +0 -2
- package/dist/components/ui/primitives/modal.js +2 -2
- package/dist/components/ui/primitives/text.js +48 -8
- package/dist/components/ui/text.js +37 -66
- package/dist/components/ui/toast.js +78 -40
- package/dist/components/ui/view.js +28 -41
- package/dist/crypto-polyfill.js +0 -0
- package/dist/crypto-polyfill.native.js +24 -0
- package/dist/index.js +1 -0
- package/dist/lib/theme/index.js +1 -2
- package/dist/lib/theme/theme.js +106 -54
- package/dist/lib/theme/tokens.js +94 -1
- package/dist/livestream-store/chat.js +0 -2
- package/dist/livestream-store/stream-key.js +1 -1
- package/dist/player-store/player-provider.js +10 -2
- package/dist/player-store/single-player-provider.js +1 -1
- package/dist/streamplace-store/stream.js +1 -1
- package/dist/ui/index.js +2 -3
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +3 -2
- package/src/components/chat/chat-box.tsx +6 -3
- package/src/components/chat/chat.tsx +1 -0
- package/src/components/mobile-player/ui/autoplay-button.tsx +1 -0
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +2 -2
- package/src/components/mobile-player/ui/viewer-loading-overlay.tsx +2 -2
- package/src/components/mobile-player/use-webrtc.tsx +41 -1
- package/src/components/mobile-player/video.native.tsx +19 -4
- package/src/components/ui/button.tsx +110 -172
- package/src/components/ui/dialog.tsx +96 -138
- package/src/components/ui/dropdown.tsx +60 -22
- package/src/components/ui/input.tsx +57 -144
- package/src/components/ui/primitives/button.tsx +0 -2
- package/src/components/ui/primitives/modal.tsx +0 -2
- package/src/components/ui/primitives/text.tsx +51 -8
- package/src/components/ui/text.tsx +42 -67
- package/src/components/ui/toast.tsx +108 -90
- package/src/components/ui/view.tsx +27 -41
- package/src/crypto-polyfill.native.tsx +24 -0
- package/src/crypto-polyfill.tsx +0 -0
- package/src/index.tsx +2 -0
- package/src/lib/theme/index.ts +0 -2
- package/src/lib/theme/theme.tsx +179 -72
- package/src/lib/theme/tokens.ts +97 -0
- package/src/livestream-store/chat.tsx +0 -3
- package/src/livestream-store/stream-key.tsx +1 -1
- package/src/player-store/player-provider.tsx +13 -1
- package/src/player-store/single-player-provider.tsx +1 -1
- package/src/streamplace-store/stream.tsx +1 -1
- package/src/ui/index.ts +0 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -11,11 +11,81 @@ import {
|
|
|
11
11
|
ViewStyle,
|
|
12
12
|
} from "react-native";
|
|
13
13
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
14
|
-
import { useTheme } from "../../lib/theme/theme";
|
|
15
14
|
|
|
16
|
-
import {
|
|
15
|
+
import { useTheme } from "../../ui";
|
|
17
16
|
|
|
18
|
-
type
|
|
17
|
+
type ToastConfig = {
|
|
18
|
+
title: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
duration?: number;
|
|
21
|
+
actionLabel?: string;
|
|
22
|
+
onAction?: () => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type ToastState = {
|
|
26
|
+
id: string;
|
|
27
|
+
open: boolean;
|
|
28
|
+
title: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
duration: number;
|
|
31
|
+
actionLabel?: string;
|
|
32
|
+
onAction?: () => void;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
class ToastManager {
|
|
36
|
+
private listeners: Set<(state: ToastState | null) => void> = new Set();
|
|
37
|
+
private currentToast: ToastState | null = null;
|
|
38
|
+
private timeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
39
|
+
|
|
40
|
+
show(config: ToastConfig) {
|
|
41
|
+
if (this.timeoutId) {
|
|
42
|
+
clearTimeout(this.timeoutId);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const toast: ToastState = {
|
|
46
|
+
id: Math.random().toString(36).substr(2, 9),
|
|
47
|
+
open: true,
|
|
48
|
+
title: config.title,
|
|
49
|
+
description: config.description,
|
|
50
|
+
duration: config.duration ?? 3,
|
|
51
|
+
actionLabel: config.actionLabel,
|
|
52
|
+
onAction: config.onAction,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
this.currentToast = toast;
|
|
56
|
+
this.notifyListeners();
|
|
57
|
+
|
|
58
|
+
if (toast.duration > 0) {
|
|
59
|
+
this.timeoutId = setTimeout(() => {
|
|
60
|
+
this.hide();
|
|
61
|
+
}, toast.duration * 1000);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
hide() {
|
|
66
|
+
if (this.timeoutId) {
|
|
67
|
+
clearTimeout(this.timeoutId);
|
|
68
|
+
this.timeoutId = null;
|
|
69
|
+
}
|
|
70
|
+
this.currentToast = null;
|
|
71
|
+
this.notifyListeners();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
subscribe(listener: (state: ToastState | null) => void) {
|
|
75
|
+
this.listeners.add(listener);
|
|
76
|
+
return () => {
|
|
77
|
+
this.listeners.delete(listener);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private notifyListeners() {
|
|
82
|
+
this.listeners.forEach((listener) => listener(this.currentToast));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const toastManager = new ToastManager();
|
|
87
|
+
|
|
88
|
+
export const toast = {
|
|
19
89
|
show: (
|
|
20
90
|
title: string,
|
|
21
91
|
description?: string,
|
|
@@ -24,103 +94,51 @@ type ToastController = {
|
|
|
24
94
|
actionLabel?: string;
|
|
25
95
|
onAction?: () => void;
|
|
26
96
|
},
|
|
27
|
-
) =>
|
|
28
|
-
|
|
97
|
+
) => {
|
|
98
|
+
toastManager.show({
|
|
99
|
+
title,
|
|
100
|
+
description,
|
|
101
|
+
...options,
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
hide: () => toastManager.hide(),
|
|
29
105
|
};
|
|
30
106
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
title: string;
|
|
34
|
-
description?: string;
|
|
35
|
-
actionLabel?: string;
|
|
36
|
-
onAction?: () => void;
|
|
37
|
-
duration?: number;
|
|
38
|
-
setOpen: (open: boolean) => void;
|
|
39
|
-
setTitle: (title: string) => void;
|
|
40
|
-
setDescription: (description: string) => void;
|
|
41
|
-
setActionLabel: (label: string) => void;
|
|
42
|
-
setOnAction: (cb?: () => void) => void;
|
|
43
|
-
setDuration: (duration: number) => void;
|
|
44
|
-
toastController: ToastController;
|
|
45
|
-
};
|
|
107
|
+
export function useToast() {
|
|
108
|
+
const [toastState, setToastState] = useState<ToastState | null>(null);
|
|
46
109
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
*/
|
|
51
|
-
export function useToast(
|
|
52
|
-
initial: {
|
|
53
|
-
title?: string;
|
|
54
|
-
description?: string;
|
|
55
|
-
duration?: number;
|
|
56
|
-
actionLabel?: string;
|
|
57
|
-
onAction?: () => void;
|
|
58
|
-
} = {},
|
|
59
|
-
) {
|
|
60
|
-
const [open, setOpen] = useState(false);
|
|
61
|
-
const [title, setTitle] = useState(initial.title ?? "");
|
|
62
|
-
const [description, setDescription] = useState(initial.description ?? "");
|
|
63
|
-
const [duration, setDuration] = useState(initial.duration ?? 3);
|
|
64
|
-
const [actionLabel, setActionLabel] = useState(
|
|
65
|
-
initial.actionLabel ?? "Action",
|
|
66
|
-
);
|
|
67
|
-
const [onAction, setOnAction] = useState<(() => void) | undefined>(
|
|
68
|
-
initial.onAction,
|
|
69
|
-
);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
return toastManager.subscribe(setToastState);
|
|
112
|
+
}, []);
|
|
70
113
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
},
|
|
80
|
-
) => {
|
|
81
|
-
setTitle(toastTitle);
|
|
82
|
-
setDescription(toastDescription ?? "");
|
|
83
|
-
setDuration(options?.duration ?? 3);
|
|
84
|
-
setActionLabel(options?.actionLabel ?? "Action");
|
|
85
|
-
setOnAction(options?.onAction);
|
|
86
|
-
setOpen(true);
|
|
87
|
-
},
|
|
88
|
-
[],
|
|
89
|
-
);
|
|
114
|
+
return {
|
|
115
|
+
toast: toastState,
|
|
116
|
+
...toast,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function ToastProvider() {
|
|
121
|
+
const [toastState, setToastState] = useState<ToastState | null>(null);
|
|
90
122
|
|
|
91
|
-
|
|
92
|
-
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
return toastManager.subscribe(setToastState);
|
|
93
125
|
}, []);
|
|
94
126
|
|
|
95
|
-
|
|
96
|
-
|
|
127
|
+
if (!toastState?.open) return null;
|
|
128
|
+
|
|
129
|
+
return (
|
|
97
130
|
<Toast
|
|
98
|
-
open={open}
|
|
99
|
-
onOpenChange={
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
131
|
+
open={toastState.open}
|
|
132
|
+
onOpenChange={(open) => {
|
|
133
|
+
if (!open) toastManager.hide();
|
|
134
|
+
}}
|
|
135
|
+
title={toastState.title}
|
|
136
|
+
description={toastState.description}
|
|
137
|
+
actionLabel={toastState.actionLabel}
|
|
138
|
+
onAction={toastState.onAction}
|
|
139
|
+
duration={toastState.duration}
|
|
105
140
|
/>
|
|
106
141
|
);
|
|
107
|
-
|
|
108
|
-
return {
|
|
109
|
-
open,
|
|
110
|
-
title,
|
|
111
|
-
description,
|
|
112
|
-
actionLabel,
|
|
113
|
-
onAction,
|
|
114
|
-
duration,
|
|
115
|
-
setOpen,
|
|
116
|
-
setTitle,
|
|
117
|
-
setDescription,
|
|
118
|
-
setActionLabel,
|
|
119
|
-
setOnAction,
|
|
120
|
-
setDuration,
|
|
121
|
-
toastController: { show, hide },
|
|
122
|
-
ToastComponent,
|
|
123
|
-
};
|
|
124
142
|
}
|
|
125
143
|
|
|
126
144
|
type ToastProps = {
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
ViewProps as RNViewProps,
|
|
6
6
|
ViewStyle,
|
|
7
7
|
} from "react-native";
|
|
8
|
-
import { borderRadius as radius, spacing } from "../../lib/theme/atoms";
|
|
9
8
|
import { useTheme } from "../../lib/theme/theme";
|
|
9
|
+
import * as zero from "../../ui";
|
|
10
10
|
|
|
11
11
|
// View variants using class-variance-authority pattern
|
|
12
12
|
const viewVariants = cva("", {
|
|
@@ -121,72 +121,64 @@ export const View = forwardRef<RNView, ViewProps>(
|
|
|
121
121
|
},
|
|
122
122
|
ref,
|
|
123
123
|
) => {
|
|
124
|
-
const {
|
|
124
|
+
const { zero: zt } = useTheme();
|
|
125
125
|
|
|
126
|
-
// Map variant to styles
|
|
126
|
+
// Map variant to styles using theme.zero
|
|
127
127
|
const variantStyles: ViewStyle = (() => {
|
|
128
128
|
switch (variant) {
|
|
129
129
|
case "card":
|
|
130
130
|
return {
|
|
131
|
-
|
|
132
|
-
borderRadius:
|
|
133
|
-
|
|
134
|
-
shadowOffset: { width: 0, height: 2 },
|
|
135
|
-
shadowOpacity: 0.1,
|
|
136
|
-
shadowRadius: 4,
|
|
137
|
-
elevation: 3,
|
|
131
|
+
...zt.bg.card,
|
|
132
|
+
borderRadius: zero.borderRadius.lg,
|
|
133
|
+
...zero.shadows.md,
|
|
138
134
|
};
|
|
139
135
|
case "overlay":
|
|
140
|
-
return
|
|
141
|
-
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
142
|
-
};
|
|
136
|
+
return zt.bg.overlay;
|
|
143
137
|
case "surface":
|
|
144
|
-
return
|
|
145
|
-
backgroundColor: theme.colors.background,
|
|
146
|
-
};
|
|
138
|
+
return zt.bg.background;
|
|
147
139
|
case "container":
|
|
148
140
|
return {
|
|
149
|
-
|
|
150
|
-
|
|
141
|
+
...zt.bg.background,
|
|
142
|
+
...zero.p[8],
|
|
151
143
|
};
|
|
152
144
|
default:
|
|
153
145
|
return {};
|
|
154
146
|
}
|
|
155
147
|
})();
|
|
156
148
|
|
|
157
|
-
// Map padding to
|
|
149
|
+
// Map padding to zero tokens
|
|
158
150
|
const paddingValue = (() => {
|
|
159
151
|
switch (padding) {
|
|
160
152
|
case "xs":
|
|
161
|
-
return
|
|
153
|
+
return zero.p[1];
|
|
162
154
|
case "sm":
|
|
163
|
-
return
|
|
155
|
+
return zero.p[2];
|
|
164
156
|
case "md":
|
|
165
|
-
return
|
|
157
|
+
return zero.p[4];
|
|
166
158
|
case "lg":
|
|
167
|
-
return
|
|
159
|
+
return zero.p[6];
|
|
168
160
|
case "xl":
|
|
169
|
-
return
|
|
161
|
+
return zero.p[8];
|
|
170
162
|
default:
|
|
171
|
-
return
|
|
163
|
+
return {};
|
|
172
164
|
}
|
|
173
165
|
})();
|
|
174
166
|
|
|
175
|
-
// Map margin to
|
|
167
|
+
// Map margin to zero tokens
|
|
176
168
|
const marginValue = (() => {
|
|
177
169
|
switch (margin) {
|
|
178
170
|
case "xs":
|
|
179
|
-
return
|
|
171
|
+
return zero.m[1];
|
|
180
172
|
case "sm":
|
|
181
|
-
return
|
|
173
|
+
return zero.m[2];
|
|
182
174
|
case "md":
|
|
183
|
-
return
|
|
175
|
+
return zero.m[4];
|
|
184
176
|
case "lg":
|
|
185
|
-
return
|
|
177
|
+
return zero.m[6];
|
|
186
178
|
case "xl":
|
|
187
|
-
return
|
|
179
|
+
return zero.m[8];
|
|
188
180
|
default:
|
|
189
|
-
return
|
|
181
|
+
return {};
|
|
190
182
|
}
|
|
191
183
|
})();
|
|
192
184
|
|
|
@@ -262,8 +254,8 @@ export const View = forwardRef<RNView, ViewProps>(
|
|
|
262
254
|
|
|
263
255
|
const computedStyle: ViewStyle = {
|
|
264
256
|
...variantStyles,
|
|
265
|
-
...
|
|
266
|
-
...
|
|
257
|
+
...paddingValue,
|
|
258
|
+
...marginValue,
|
|
267
259
|
flexDirection,
|
|
268
260
|
alignItems,
|
|
269
261
|
justifyContent,
|
|
@@ -278,13 +270,7 @@ export const View = forwardRef<RNView, ViewProps>(
|
|
|
278
270
|
...(borderColor && { borderColor }),
|
|
279
271
|
...(borderWidth !== undefined && { borderWidth }),
|
|
280
272
|
...(borderRadius !== undefined && { borderRadius }),
|
|
281
|
-
...(shadow &&
|
|
282
|
-
shadowColor: "#000",
|
|
283
|
-
shadowOffset: { width: 0, height: 2 },
|
|
284
|
-
shadowOpacity: 0.1,
|
|
285
|
-
shadowRadius: 4,
|
|
286
|
-
elevation: 3,
|
|
287
|
-
}),
|
|
273
|
+
...(shadow && zero.shadows.md),
|
|
288
274
|
};
|
|
289
275
|
|
|
290
276
|
const finalStyle = Array.isArray(style)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// awkward use of require()? you betcha. but import() with Metro causes it to try and
|
|
2
|
+
// resolve the package at compile-time even if not installed, so here we are.
|
|
3
|
+
let rnqc: any | null = null;
|
|
4
|
+
let expoCrypto: any | null = null;
|
|
5
|
+
try {
|
|
6
|
+
rnqc = require("react-native-quick-crypto");
|
|
7
|
+
} catch (err) {}
|
|
8
|
+
try {
|
|
9
|
+
expoCrypto = require("expo-crypto");
|
|
10
|
+
} catch (err) {}
|
|
11
|
+
|
|
12
|
+
if (!rnqc && !expoCrypto) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
"Livestreaming requires one of react-native-quick-crypto or expo-crypto",
|
|
15
|
+
);
|
|
16
|
+
} else if (!rnqc && expoCrypto) {
|
|
17
|
+
// @atproto/crypto dependencies expect crypto.getRandomValues to be a function
|
|
18
|
+
if (typeof globalThis.crypto === "undefined") {
|
|
19
|
+
globalThis.crypto = {} as any;
|
|
20
|
+
}
|
|
21
|
+
if (typeof globalThis.crypto.getRandomValues === "undefined") {
|
|
22
|
+
globalThis.crypto.getRandomValues = expoCrypto.getRandomValues;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
File without changes
|
package/src/index.tsx
CHANGED
package/src/lib/theme/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ export {
|
|
|
3
3
|
ThemeProvider,
|
|
4
4
|
createThemeColors,
|
|
5
5
|
createThemeIcons,
|
|
6
|
-
createThemeStyles,
|
|
7
6
|
createThemedStyles,
|
|
8
7
|
darkTheme,
|
|
9
8
|
lightTheme,
|
|
@@ -11,7 +10,6 @@ export {
|
|
|
11
10
|
useTheme,
|
|
12
11
|
type Theme,
|
|
13
12
|
type ThemeIcons,
|
|
14
|
-
type ThemeStyles,
|
|
15
13
|
} from "./theme";
|
|
16
14
|
|
|
17
15
|
// Design tokens
|