@streamplace/components 0.7.9 → 0.7.13

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 (48) hide show
  1. package/dist/assets/emoji-data.json +19371 -0
  2. package/dist/components/chat/chat-box.js +19 -2
  3. package/dist/components/chat/chat-message.js +12 -4
  4. package/dist/components/chat/chat.js +15 -4
  5. package/dist/components/chat/mod-view.js +15 -8
  6. package/dist/components/dashboard/chat-panel.js +38 -0
  7. package/dist/components/dashboard/header.js +80 -0
  8. package/dist/components/dashboard/index.js +14 -0
  9. package/dist/components/dashboard/information-widget.js +234 -0
  10. package/dist/components/dashboard/mod-actions.js +71 -0
  11. package/dist/components/dashboard/problems.js +74 -0
  12. package/dist/components/mobile-player/ui/viewer-context-menu.js +15 -6
  13. package/dist/components/ui/button.js +2 -2
  14. package/dist/components/ui/dropdown.js +20 -1
  15. package/dist/components/ui/index.js +2 -0
  16. package/dist/components/ui/info-box.js +31 -0
  17. package/dist/components/ui/info-row.js +23 -0
  18. package/dist/components/ui/toast.js +43 -0
  19. package/dist/index.js +3 -1
  20. package/dist/lib/theme/atoms.js +66 -45
  21. package/dist/lib/theme/tokens.js +285 -12
  22. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  23. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/56540125 +0 -0
  24. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/67b1eb60 +0 -0
  25. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/7c275f90 +0 -0
  26. package/package.json +2 -2
  27. package/src/assets/emoji-data.json +19371 -0
  28. package/src/components/chat/chat-box.tsx +19 -1
  29. package/src/components/chat/chat-message.tsx +22 -14
  30. package/src/components/chat/chat.tsx +21 -6
  31. package/src/components/chat/mod-view.tsx +24 -6
  32. package/src/components/dashboard/chat-panel.tsx +80 -0
  33. package/src/components/dashboard/header.tsx +170 -0
  34. package/src/components/dashboard/index.tsx +5 -0
  35. package/src/components/dashboard/information-widget.tsx +526 -0
  36. package/src/components/dashboard/mod-actions.tsx +133 -0
  37. package/src/components/dashboard/problems.tsx +151 -0
  38. package/src/components/mobile-player/ui/viewer-context-menu.tsx +67 -38
  39. package/src/components/ui/button.tsx +2 -2
  40. package/src/components/ui/dropdown.tsx +38 -3
  41. package/src/components/ui/index.ts +2 -0
  42. package/src/components/ui/info-box.tsx +60 -0
  43. package/src/components/ui/info-row.tsx +48 -0
  44. package/src/components/ui/toast.tsx +110 -0
  45. package/src/index.tsx +3 -0
  46. package/src/lib/theme/atoms.ts +97 -43
  47. package/src/lib/theme/tokens.ts +285 -12
  48. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProblemsWrapper = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const lucide_react_native_1 = require("lucide-react-native");
7
+ const react_1 = require("react");
8
+ const react_native_1 = require("react-native");
9
+ const livestream_store_1 = require("../../livestream-store");
10
+ const zero = tslib_1.__importStar(require("../../ui"));
11
+ const { bg, r, borders, p, text, layout, gap } = zero;
12
+ const Problems = ({ probs, onIgnore, }) => {
13
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [gap.all[3]], children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [text.white, { fontSize: 24, fontWeight: "bold" }], children: "Optimize Your Stream" }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [text.gray[300]], children: "We've found a few things that could improve your stream's reliability." })] }), probs.map((p) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
14
+ gap.all[2],
15
+ layout.flex.row,
16
+ layout.flex.alignCenter,
17
+ { gap: 8, alignItems: "flex-start" },
18
+ ], children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
19
+ r.sm,
20
+ p[2],
21
+ {
22
+ width: 82,
23
+ textAlign: "center",
24
+ backgroundColor: p.severity === "error"
25
+ ? "#7f1d1d"
26
+ : p.severity === "warning"
27
+ ? "#7c2d12"
28
+ : "#1e3a8a",
29
+ color: "white",
30
+ fontSize: 12,
31
+ },
32
+ ], children: p.severity }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [{ flex: 1 }, gap.all[1]], children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [text.white, { fontWeight: "600" }], children: p.code }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [text.gray[400], { fontSize: 14 }], children: p.message }), p.link && ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: () => p.link && react_native_1.Linking.openURL(p.link), children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
33
+ layout.flex.row,
34
+ layout.flex.alignCenter,
35
+ gap.all[2],
36
+ ], children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [{ color: "#3b82f6", fontSize: 14 }], children: "Learn More" }), (0, jsx_runtime_1.jsx)(lucide_react_native_1.ExternalLink, { size: 12, color: "#3b82f6" })] }) }))] })] }) }, p.message))), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: onIgnore, style: [
37
+ bg.blue[600],
38
+ r.md,
39
+ p[3],
40
+ layout.flex.center,
41
+ { marginTop: 16 },
42
+ ], children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [text.white, { fontWeight: "600" }], children: "Ignore" }) })] }));
43
+ };
44
+ const ProblemsWrapper = ({ children, }) => {
45
+ const problems = (0, livestream_store_1.useLivestreamStore)((x) => x.problems);
46
+ const [dismiss, setDismiss] = (0, react_1.useState)(false);
47
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
48
+ { position: "relative", flex: 1 },
49
+ layout.flex.center,
50
+ { flexBasis: 0 },
51
+ ], children: [children, problems.length > 0 && !dismiss && ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
52
+ {
53
+ position: "absolute",
54
+ top: 0,
55
+ left: 0,
56
+ right: 0,
57
+ bottom: 0,
58
+ backgroundColor: "rgba(0, 0, 0, 0.8)",
59
+ zIndex: 100,
60
+ },
61
+ layout.flex.center,
62
+ { justifyContent: "flex-start" },
63
+ p[8],
64
+ ], children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
65
+ bg.gray[900],
66
+ borders.color.gray[700],
67
+ borders.width.thin,
68
+ r.lg,
69
+ p[4],
70
+ { maxWidth: 700, width: "100%" },
71
+ ], children: (0, jsx_runtime_1.jsx)(Problems, { probs: problems, onIgnore: () => setDismiss(true) }) }) }))] }));
72
+ };
73
+ exports.ProblemsWrapper = ProblemsWrapper;
74
+ exports.default = Problems;
@@ -5,11 +5,12 @@ exports.ReportButton = ReportButton;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const dropdown_menu_1 = require("@rn-primitives/dropdown-menu");
7
7
  const lucide_react_native_1 = require("lucide-react-native");
8
+ const react_native_1 = require("react-native");
8
9
  const theme_1 = require("../../../lib/theme");
9
10
  const livestream_store_1 = require("../../../livestream-store");
10
11
  const player_store_1 = require("../../../player-store/");
11
12
  const ui_1 = require("../../ui");
12
- function ContextMenu() {
13
+ function ContextMenu({ dropdownPortalContainer, }) {
13
14
  const quality = (0, player_store_1.usePlayerStore)((x) => x.selectedRendition);
14
15
  const setQuality = (0, player_store_1.usePlayerStore)((x) => x.setSelectedRendition);
15
16
  const qualities = (0, livestream_store_1.useLivestreamStore)((x) => x.renditions);
@@ -17,16 +18,24 @@ function ContextMenu() {
17
18
  const setProtocol = (0, player_store_1.usePlayerStore)((x) => x.setProtocol);
18
19
  const debugInfo = (0, player_store_1.usePlayerStore)((x) => x.showDebugInfo);
19
20
  const setShowDebugInfo = (0, player_store_1.usePlayerStore)((x) => x.setShowDebugInfo);
21
+ const livestream = (0, livestream_store_1.useLivestreamStore)((x) => x.livestream);
22
+ const setReportModalOpen = (0, player_store_1.usePlayerStore)((x) => x.setReportModalOpen);
23
+ const setReportSubject = (0, player_store_1.usePlayerStore)((x) => x.setReportSubject);
20
24
  const lowLatency = protocol === "webrtc";
21
25
  const setLowLatency = (value) => {
22
26
  setProtocol(value ? player_store_1.PlayerProtocol.WEBRTC : player_store_1.PlayerProtocol.HLS);
23
27
  };
24
- return ((0, jsx_runtime_1.jsxs)(ui_1.DropdownMenu, { children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuTrigger, { children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Settings, { color: theme_1.colors.gray[200] }) }), (0, jsx_runtime_1.jsxs)(ui_1.ResponsiveDropdownMenuContent, { side: "top", align: "end", children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { title: "Resolution", children: (0, jsx_runtime_1.jsxs)(ui_1.DropdownMenuRadioGroup, { value: quality, onValueChange: setQuality, children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuRadioItem, { value: "source", children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Source (Original Quality)" }) }), qualities.map((r) => ((0, jsx_runtime_1.jsx)(ui_1.DropdownMenuRadioItem, { value: r.name, children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: r.name }) })))] }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { title: "Advanced", children: (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuCheckboxItem, { checked: lowLatency, onCheckedChange: () => setLowLatency(!lowLatency), children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Low Latency" }) }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuInfo, { description: "Reduces the delay between video and chat for a more real-time experience." }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { children: (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuCheckboxItem, { checked: debugInfo, onCheckedChange: () => setShowDebugInfo(!debugInfo), children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Show Debug Info" }) }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { title: "Report", children: (0, jsx_runtime_1.jsx)(ReportButton, {}) })] })] }));
28
+ // are we on mobile? then do dropdowns
29
+ const isMobile = react_native_1.Platform.OS === "ios" || react_native_1.Platform.OS === "android";
30
+ // dummy portal for mobile
31
+ const Portal = isMobile ? react_native_1.View : ui_1.DropdownMenuPortal;
32
+ // render the responsive version on mobile as we can't fullscreen there
33
+ const DropdownMenuContent = isMobile
34
+ ? ui_1.ResponsiveDropdownMenuContent
35
+ : ui_1.DropdownMenuContentWithoutPortal;
36
+ return ((0, jsx_runtime_1.jsxs)(ui_1.DropdownMenu, { children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuTrigger, { children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Settings, { color: theme_1.colors.gray[200] }) }), (0, jsx_runtime_1.jsx)(Portal, { container: dropdownPortalContainer, children: (0, jsx_runtime_1.jsxs)(DropdownMenuContent, { side: "top", align: "end", children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { title: "Resolution", children: (0, jsx_runtime_1.jsxs)(ui_1.DropdownMenuRadioGroup, { value: quality, onValueChange: setQuality, children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuRadioItem, { value: "source", children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Source (Original Quality)" }) }), qualities.map((r) => ((0, jsx_runtime_1.jsx)(ui_1.DropdownMenuRadioItem, { value: r.name, children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: r.name }) })))] }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { title: "Advanced", children: (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuCheckboxItem, { checked: lowLatency, onCheckedChange: () => setLowLatency(!lowLatency), children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Low Latency" }) }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuInfo, { description: "Reduces the delay between video and chat for a more real-time experience." }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { children: (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuCheckboxItem, { checked: debugInfo, onCheckedChange: () => setShowDebugInfo(!debugInfo), children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Show Debug Info" }) }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuGroup, { title: "Report", children: (0, jsx_runtime_1.jsx)(ReportButton, { livestream: livestream, setReportModalOpen: setReportModalOpen, setReportSubject: setReportSubject }) })] }) })] }));
25
37
  }
26
- function ReportButton() {
27
- const livestream = (0, livestream_store_1.useLivestreamStore)((x) => x.livestream);
28
- const setReportModalOpen = (0, player_store_1.usePlayerStore)((x) => x.setReportModalOpen);
29
- const setReportSubject = (0, player_store_1.usePlayerStore)((x) => x.setReportSubject);
38
+ function ReportButton({ livestream, setReportModalOpen, setReportSubject, }) {
30
39
  const { onOpenChange } = (0, dropdown_menu_1.useRootContext)();
31
40
  return ((0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: () => {
32
41
  if (!livestream)
@@ -153,8 +153,8 @@ function createStyles(theme) {
153
153
  fontWeight: "600",
154
154
  },
155
155
  pillButton: {
156
- paddingHorizontal: theme.spacing[3],
157
- paddingVertical: theme.spacing[2],
156
+ paddingHorizontal: theme.spacing[2],
157
+ paddingVertical: theme.spacing[1],
158
158
  borderRadius: tokens.borderRadius.full,
159
159
  minHeight: tokens.touchTargets.minimum / 2,
160
160
  },
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DropdownMenuInfo = exports.DropdownMenuGroup = exports.DropdownMenuSeparator = exports.DropdownMenuLabel = exports.DropdownMenuRadioItem = exports.DropdownMenuCheckboxItem = exports.DropdownMenuItem = exports.ResponsiveDropdownMenuContent = exports.DropdownMenuContent = exports.DropdownMenuSubContent = exports.DropdownMenuSubTrigger = exports.DropdownMenuBottomSheet = exports.DropdownMenuRadioGroup = exports.DropdownMenuSub = exports.DropdownMenuPortal = exports.DropdownMenuTrigger = exports.DropdownMenu = void 0;
3
+ exports.DropdownMenuInfo = exports.DropdownMenuGroup = exports.DropdownMenuSeparator = exports.DropdownMenuLabel = exports.DropdownMenuRadioItem = exports.DropdownMenuCheckboxItem = exports.DropdownMenuItem = exports.ResponsiveDropdownMenuContent = exports.DropdownMenuContentWithoutPortal = exports.DropdownMenuContent = exports.DropdownMenuSubContent = exports.DropdownMenuSubTrigger = exports.DropdownMenuBottomSheet = exports.DropdownMenuRadioGroup = exports.DropdownMenuSub = exports.DropdownMenuPortal = exports.DropdownMenuTrigger = exports.DropdownMenu = void 0;
4
4
  exports.DropdownMenuShortcut = DropdownMenuShortcut;
5
5
  const tslib_1 = require("tslib");
6
6
  const jsx_runtime_1 = require("react/jsx-runtime");
@@ -77,6 +77,25 @@ exports.DropdownMenuContent = (0, react_1.forwardRef)(({ overlayStyle, portalHos
77
77
  atoms_1.a.shadows.md,
78
78
  ], ...props }) }) }));
79
79
  });
80
+ exports.DropdownMenuContentWithoutPortal = (0, react_1.forwardRef)(({ overlayStyle, ...props }, ref) => {
81
+ return ((0, jsx_runtime_1.jsx)(DropdownMenuPrimitive.Overlay, { style: [
82
+ react_native_1.Platform.OS !== "web" ? react_native_1.StyleSheet.absoluteFill : undefined,
83
+ overlayStyle,
84
+ ], children: (0, jsx_runtime_1.jsx)(DropdownMenuPrimitive.Content, { ref: ref, style: [
85
+ { zIndex: 999999 },
86
+ atoms_1.a.sizes.minWidth[32],
87
+ atoms_1.a.sizes.maxWidth[64],
88
+ atoms_1.a.overflow.hidden,
89
+ atoms_1.a.radius.all.md,
90
+ atoms_1.a.borders.width.thin,
91
+ atoms_1.a.borders.color.gray[800],
92
+ atoms_1.bg.gray[950],
93
+ atoms_1.p[2],
94
+ atoms_1.a.shadows.md,
95
+ ], ...props }) }));
96
+ });
97
+ /// Responsive Dropdown Menu Content. On mobile this will render a *bottom sheet* that is **portaled to the root of the app**.
98
+ /// Prefer passing scoped content in as **otherwise it may crash the app**.
80
99
  exports.ResponsiveDropdownMenuContent = (0, react_1.forwardRef)(({ children, ...props }, ref) => {
81
100
  const { width } = (0, react_native_1.useWindowDimensions)();
82
101
  // On web, you might want to always use the normal dropdown
@@ -12,6 +12,8 @@ tslib_1.__exportStar(require("./button"), exports);
12
12
  tslib_1.__exportStar(require("./dialog"), exports);
13
13
  tslib_1.__exportStar(require("./dropdown"), exports);
14
14
  tslib_1.__exportStar(require("./icons"), exports);
15
+ tslib_1.__exportStar(require("./info-box"), exports);
16
+ tslib_1.__exportStar(require("./info-row"), exports);
15
17
  tslib_1.__exportStar(require("./input"), exports);
16
18
  tslib_1.__exportStar(require("./loader"), exports);
17
19
  tslib_1.__exportStar(require("./resizeable"), exports);
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InfoBox = InfoBox;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_native_1 = require("react-native");
7
+ const zero = tslib_1.__importStar(require("../../ui"));
8
+ const { bg, r, p, text, layout, gap, flex } = zero;
9
+ function InfoBox({ icon: Icon, label, value, status = "neutral", }) {
10
+ const statusColors = {
11
+ good: text.green[400],
12
+ warning: text.yellow[400],
13
+ error: text.red[400],
14
+ neutral: text.white,
15
+ };
16
+ const statusColor = statusColors[status];
17
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
18
+ flex.values[1],
19
+ layout.flex.column,
20
+ layout.flex.spaceBetween,
21
+ layout.flex.alignCenter,
22
+ bg.neutral[700],
23
+ r.sm,
24
+ p[2],
25
+ ], children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
26
+ layout.flex.row,
27
+ layout.flex.spaceBetween,
28
+ gap.all[3],
29
+ zero.w.percent[100],
30
+ ], children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [text.gray[100], { fontSize: 13, fontWeight: "500" }], children: label }), (0, jsx_runtime_1.jsx)(Icon, { size: 16, color: "#9ca3af" })] }), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [layout.flex.align.end, zero.w.percent[100]], children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [statusColor, { fontSize: 26, fontWeight: "600" }], children: value }) })] }));
31
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InfoRow = InfoRow;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_native_1 = require("react-native");
7
+ const zero = tslib_1.__importStar(require("../../ui"));
8
+ const { text, layout, py, gap } = zero;
9
+ function InfoRow({ icon: Icon, label, value, status = "neutral", }) {
10
+ const statusColors = {
11
+ good: text.green[400],
12
+ warning: text.yellow[400],
13
+ error: text.red[400],
14
+ neutral: text.white,
15
+ };
16
+ const statusColor = statusColors[status];
17
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
18
+ layout.flex.row,
19
+ layout.flex.spaceBetween,
20
+ layout.flex.alignCenter,
21
+ py[2],
22
+ ], children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [layout.flex.row, layout.flex.alignCenter, gap.all[3]], children: [(0, jsx_runtime_1.jsx)(Icon, { size: 16, color: "#9ca3af" }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [text.gray[300], { fontSize: 13, fontWeight: "500" }], children: label })] }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [statusColor, { fontSize: 13, fontWeight: "600" }], children: value })] }));
23
+ }
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useToast = useToast;
3
4
  exports.Toast = Toast;
4
5
  const jsx_runtime_1 = require("react/jsx-runtime");
5
6
  const portal_1 = require("@rn-primitives/portal");
@@ -7,6 +8,48 @@ const react_1 = require("react");
7
8
  const react_native_1 = require("react-native");
8
9
  const react_native_safe_area_context_1 = require("react-native-safe-area-context");
9
10
  const theme_1 = require("../../lib/theme/theme");
11
+ const react_2 = require("react");
12
+ /**
13
+ * useToast - a hook to manage Toast state and provide a toastController.
14
+ * Returns a ready-to-render ToastComponent.
15
+ */
16
+ function useToast(initial = {}) {
17
+ const [open, setOpen] = (0, react_1.useState)(false);
18
+ const [title, setTitle] = (0, react_1.useState)(initial.title ?? "");
19
+ const [description, setDescription] = (0, react_1.useState)(initial.description ?? "");
20
+ const [duration, setDuration] = (0, react_1.useState)(initial.duration ?? 3);
21
+ const [actionLabel, setActionLabel] = (0, react_1.useState)(initial.actionLabel ?? "Action");
22
+ const [onAction, setOnAction] = (0, react_1.useState)(initial.onAction);
23
+ const show = (0, react_2.useCallback)((toastTitle, toastDescription, options) => {
24
+ setTitle(toastTitle);
25
+ setDescription(toastDescription ?? "");
26
+ setDuration(options?.duration ?? 3);
27
+ setActionLabel(options?.actionLabel ?? "Action");
28
+ setOnAction(options?.onAction);
29
+ setOpen(true);
30
+ }, []);
31
+ const hide = (0, react_2.useCallback)(() => {
32
+ setOpen(false);
33
+ }, []);
34
+ // Ready-to-render Toast component
35
+ const ToastComponent = ((0, jsx_runtime_1.jsx)(Toast, { open: open, onOpenChange: setOpen, title: title, description: description, actionLabel: actionLabel, onAction: onAction, duration: duration }));
36
+ return {
37
+ open,
38
+ title,
39
+ description,
40
+ actionLabel,
41
+ onAction,
42
+ duration,
43
+ setOpen,
44
+ setTitle,
45
+ setDescription,
46
+ setActionLabel,
47
+ setOnAction,
48
+ setDuration,
49
+ toastController: { show, hide },
50
+ ToastComponent,
51
+ };
52
+ }
10
53
  function Toast({ open, onOpenChange, title, description, actionLabel = "Action", onAction, duration = 3, }) {
11
54
  const [seconds, setSeconds] = (0, react_1.useState)(duration);
12
55
  const insets = (0, react_native_safe_area_context_1.useSafeAreaInsets)();
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VideoRetry = exports.zero = exports.ui = exports.PlayerUI = exports.Player = exports.usePlayerContext = exports.withPlayerProvider = exports.PlayerProvider = void 0;
3
+ exports.Dashboard = exports.VideoRetry = exports.zero = exports.ui = exports.PlayerUI = exports.Player = exports.usePlayerContext = exports.withPlayerProvider = exports.PlayerProvider = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  // barrel file :)
6
6
  tslib_1.__exportStar(require("./livestream-provider"), exports);
@@ -30,3 +30,5 @@ Object.defineProperty(exports, "VideoRetry", { enumerable: true, get: function (
30
30
  tslib_1.__exportStar(require("./lib/system-messages"), exports);
31
31
  tslib_1.__exportStar(require("./components/share/sharesheet"), exports);
32
32
  tslib_1.__exportStar(require("./components/keep-awake"), exports);
33
+ // Dashboard components
34
+ exports.Dashboard = tslib_1.__importStar(require("./components/dashboard"));
@@ -89,15 +89,38 @@ exports.layout = {
89
89
  spaceEvenly: {
90
90
  justifyContent: "space-evenly",
91
91
  },
92
+ direction: pairify({
93
+ row: "row",
94
+ column: "column",
95
+ "row-reverse": "row-reverse",
96
+ "column-reverse": "column-reverse",
97
+ }, "flexDirection"),
98
+ justify: pairify({
99
+ start: "flex-start",
100
+ end: "flex-end",
101
+ center: "center",
102
+ between: "space-between",
103
+ around: "space-around",
104
+ evenly: "space-evenly",
105
+ }, "justifyContent"),
106
+ align: pairify({
107
+ start: "flex-start",
108
+ end: "flex-end",
109
+ center: "center",
110
+ stretch: "stretch",
111
+ baseline: "baseline",
112
+ }, "alignItems"),
113
+ wrap: pairify({
114
+ wrap: "wrap",
115
+ nowrap: "nowrap",
116
+ reverse: "wrap-reverse",
117
+ }, "flexWrap"),
92
118
  },
93
- position: {
94
- absolute: {
95
- position: "absolute",
96
- },
97
- relative: {
98
- position: "relative",
99
- },
100
- },
119
+ position: pairify({
120
+ absolute: "absolute",
121
+ relative: "relative",
122
+ static: "static",
123
+ }, "position"),
101
124
  };
102
125
  // Enhanced border utilities with pairified colors and widths
103
126
  exports.borders = {
@@ -106,11 +129,11 @@ exports.borders = {
106
129
  medium: 2,
107
130
  thick: 4,
108
131
  }, "borderWidth"),
109
- style: {
110
- solid: { borderStyle: "solid" },
111
- dashed: { borderStyle: "dashed" },
112
- dotted: { borderStyle: "dotted" },
113
- },
132
+ style: pairify({
133
+ solid: "solid",
134
+ dashed: "dashed",
135
+ dotted: "dotted",
136
+ }, "borderStyle"),
114
137
  // Pairified color borders
115
138
  color: pairify(tokens_1.colors, "borderColor"),
116
139
  // Top border utilities
@@ -278,19 +301,19 @@ exports.zIndex = pairify({
278
301
  auto: "auto",
279
302
  }, "zIndex");
280
303
  // Overflow utilities
281
- exports.overflow = {
282
- visible: { overflow: "visible" },
283
- hidden: { overflow: "hidden" },
284
- scroll: { overflow: "scroll" },
285
- };
304
+ exports.overflow = pairify({
305
+ visible: "visible",
306
+ hidden: "hidden",
307
+ scroll: "scroll",
308
+ }, "overflow");
286
309
  // Text alignment utilities
287
- exports.textAlign = {
288
- left: { textAlign: "left" },
289
- center: { textAlign: "center" },
290
- right: { textAlign: "right" },
291
- justify: { textAlign: "justify" },
292
- auto: { textAlign: "auto" },
293
- };
310
+ exports.textAlign = pairify({
311
+ left: "left",
312
+ center: "center",
313
+ right: "right",
314
+ justify: "justify",
315
+ auto: "auto",
316
+ }, "textAlign");
294
317
  // Font weight utilities
295
318
  exports.fontWeight = pairify({
296
319
  thin: "100",
@@ -346,28 +369,26 @@ exports.letterSpacing = pairify({
346
369
  widest: 1,
347
370
  }, "letterSpacing");
348
371
  // Text transform utilities
349
- exports.textTransform = {
350
- uppercase: { textTransform: "uppercase" },
351
- lowercase: { textTransform: "lowercase" },
352
- capitalize: { textTransform: "capitalize" },
353
- none: { textTransform: "none" },
354
- };
372
+ exports.textTransform = pairify({
373
+ uppercase: "uppercase",
374
+ lowercase: "lowercase",
375
+ capitalize: "capitalize",
376
+ none: "none",
377
+ }, "textTransform");
355
378
  // Text decoration utilities
356
- exports.textDecoration = {
357
- none: { textDecorationLine: "none" },
358
- underline: { textDecorationLine: "underline" },
359
- lineThrough: { textDecorationLine: "line-through" },
360
- underlineLineThrough: {
361
- textDecorationLine: "underline line-through",
362
- },
363
- };
379
+ exports.textDecoration = pairify({
380
+ none: "none",
381
+ underline: "underline",
382
+ lineThrough: "line-through",
383
+ underlineLineThrough: "underline line-through",
384
+ }, "textDecorationLine");
364
385
  // Text align vertical utilities (React Native specific)
365
- exports.textAlignVertical = {
366
- auto: { textAlignVertical: "auto" },
367
- top: { textAlignVertical: "top" },
368
- bottom: { textAlignVertical: "bottom" },
369
- center: { textAlignVertical: "center" },
370
- };
386
+ exports.textAlignVertical = pairify({
387
+ auto: "auto",
388
+ top: "top",
389
+ bottom: "bottom",
390
+ center: "center",
391
+ }, "textAlignVertical");
371
392
  // Transform utilities
372
393
  exports.transforms = {
373
394
  rotate: pairify({