@streamplace/components 0.7.34 → 0.8.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 (64) hide show
  1. package/dist/components/content-metadata/content-metadata-form.js +404 -0
  2. package/dist/components/content-metadata/content-rights.js +78 -0
  3. package/dist/components/content-metadata/content-warnings.js +68 -0
  4. package/dist/components/content-metadata/index.js +11 -0
  5. package/dist/components/dashboard/header.js +16 -2
  6. package/dist/components/dashboard/problems.js +29 -28
  7. package/dist/components/mobile-player/player.js +4 -0
  8. package/dist/components/mobile-player/ui/report-modal.js +3 -2
  9. package/dist/components/mobile-player/ui/viewer-context-menu.js +44 -1
  10. package/dist/components/ui/button.js +9 -9
  11. package/dist/components/ui/checkbox.js +87 -0
  12. package/dist/components/ui/dialog.js +188 -83
  13. package/dist/components/ui/dropdown.js +15 -10
  14. package/dist/components/ui/icons.js +6 -0
  15. package/dist/components/ui/primitives/button.js +0 -7
  16. package/dist/components/ui/primitives/input.js +13 -1
  17. package/dist/components/ui/primitives/modal.js +2 -2
  18. package/dist/components/ui/select.js +89 -0
  19. package/dist/components/ui/textarea.js +23 -4
  20. package/dist/components/ui/toast.js +464 -114
  21. package/dist/components/ui/tooltip.js +103 -0
  22. package/dist/index.js +2 -0
  23. package/dist/lib/metadata-constants.js +157 -0
  24. package/dist/lib/theme/theme.js +5 -3
  25. package/dist/lib/theme/tokens.js +9 -0
  26. package/dist/streamplace-provider/index.js +14 -4
  27. package/dist/streamplace-store/content-metadata-actions.js +118 -0
  28. package/dist/streamplace-store/graph.js +195 -0
  29. package/dist/streamplace-store/streamplace-store.js +18 -5
  30. package/dist/streamplace-store/user.js +67 -7
  31. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  32. package/package.json +3 -3
  33. package/src/components/content-metadata/content-metadata-form.tsx +761 -0
  34. package/src/components/content-metadata/content-rights.tsx +104 -0
  35. package/src/components/content-metadata/content-warnings.tsx +100 -0
  36. package/src/components/content-metadata/index.tsx +18 -0
  37. package/src/components/dashboard/header.tsx +37 -3
  38. package/src/components/dashboard/index.tsx +1 -1
  39. package/src/components/dashboard/problems.tsx +57 -46
  40. package/src/components/mobile-player/player.tsx +5 -0
  41. package/src/components/mobile-player/ui/report-modal.tsx +13 -7
  42. package/src/components/mobile-player/ui/viewer-context-menu.tsx +100 -1
  43. package/src/components/ui/button.tsx +10 -13
  44. package/src/components/ui/checkbox.tsx +147 -0
  45. package/src/components/ui/dialog.tsx +319 -99
  46. package/src/components/ui/dropdown.tsx +27 -13
  47. package/src/components/ui/icons.tsx +14 -0
  48. package/src/components/ui/primitives/button.tsx +0 -7
  49. package/src/components/ui/primitives/input.tsx +19 -2
  50. package/src/components/ui/primitives/modal.tsx +4 -2
  51. package/src/components/ui/select.tsx +175 -0
  52. package/src/components/ui/textarea.tsx +47 -29
  53. package/src/components/ui/toast.tsx +785 -179
  54. package/src/components/ui/tooltip.tsx +131 -0
  55. package/src/index.tsx +3 -0
  56. package/src/lib/metadata-constants.ts +180 -0
  57. package/src/lib/theme/theme.tsx +10 -6
  58. package/src/lib/theme/tokens.ts +9 -0
  59. package/src/streamplace-provider/index.tsx +20 -2
  60. package/src/streamplace-store/content-metadata-actions.tsx +142 -0
  61. package/src/streamplace-store/graph.tsx +232 -0
  62. package/src/streamplace-store/streamplace-store.tsx +30 -4
  63. package/src/streamplace-store/user.tsx +71 -7
  64. package/tsconfig.tsbuildinfo +1 -1
@@ -8,47 +8,49 @@ const react_1 = require("react");
8
8
  const react_native_1 = require("react-native");
9
9
  const livestream_store_1 = require("../../livestream-store");
10
10
  const zero = tslib_1.__importStar(require("../../ui"));
11
+ const ui_1 = require("../ui");
11
12
  const { bg, r, borders, p, text, layout, gap } = zero;
13
+ const getIcon = (severity) => {
14
+ switch (severity) {
15
+ case "error":
16
+ return (0, jsx_runtime_1.jsx)(lucide_react_native_1.CircleX, { size: 24, color: "white" });
17
+ case "warning":
18
+ return (0, jsx_runtime_1.jsx)(lucide_react_native_1.CircleAlert, { size: 24, color: "white" });
19
+ case "info":
20
+ return (0, jsx_runtime_1.jsx)(lucide_react_native_1.Info, { size: 24, color: "white" });
21
+ default:
22
+ return (0, jsx_runtime_1.jsx)(lucide_react_native_1.Sparkle, { size: 24, color: "white" });
23
+ }
24
+ };
12
25
  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: [
26
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [gap.all[4]], children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [gap.all[2]], children: [(0, jsx_runtime_1.jsx)(ui_1.Text, { size: "2xl", style: [text.white, { fontWeight: "600" }], children: "Optimize Your Stream" }), (0, jsx_runtime_1.jsx)(ui_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
27
  gap.all[2],
15
28
  layout.flex.row,
16
29
  layout.flex.alignCenter,
17
30
  { gap: 8, alignItems: "flex-start" },
18
- ], children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
19
- r.sm,
20
- p[2],
31
+ ], children: [(0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
32
+ zero.r.full,
33
+ zero.p[1],
21
34
  {
22
- width: 82,
23
- textAlign: "center",
24
35
  backgroundColor: p.severity === "error"
25
36
  ? "#7f1d1d"
26
37
  : p.severity === "warning"
27
38
  ? "#7c2d12"
28
39
  : "#1e3a8a",
29
- color: "white",
30
- fontSize: 12,
31
40
  },
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: [
41
+ ], children: getIcon(p.severity) }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [{ flex: 1 }, gap.all[1]], children: [(0, jsx_runtime_1.jsx)(ui_1.Text, { style: [text.white, { fontWeight: "600" }], children: p.code }), (0, jsx_runtime_1.jsx)(ui_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
42
  layout.flex.row,
34
43
  layout.flex.alignCenter,
35
44
  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" }) })] }));
45
+ ], children: [(0, jsx_runtime_1.jsx)(ui_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.View, { style: [layout.flex.row, layout.flex.justify.end], children: (0, jsx_runtime_1.jsx)(ui_1.Button, { onPress: onIgnore, variant: "secondary", children: (0, jsx_runtime_1.jsx)(ui_1.Text, { style: [text.white, { fontWeight: "600" }], children: "Acknowledge" }) }) })] }));
43
46
  };
44
- const ProblemsWrapper = ({ children, }) => {
47
+ exports.ProblemsWrapper = (0, react_1.forwardRef)(({ children }, ref) => {
45
48
  const problems = (0, livestream_store_1.useLivestreamStore)((x) => x.problems);
46
49
  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: [
50
+ (0, react_1.useImperativeHandle)(ref, () => ({
51
+ setDismiss,
52
+ }));
53
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [children, problems.length > 0 && !dismiss && ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
52
54
  {
53
55
  position: "absolute",
54
56
  top: 0,
@@ -60,15 +62,14 @@ const ProblemsWrapper = ({ children, }) => {
60
62
  },
61
63
  layout.flex.center,
62
64
  { justifyContent: "flex-start" },
63
- p[8],
65
+ p[12],
64
66
  ], children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
65
- bg.gray[900],
66
- borders.color.gray[700],
67
+ bg.neutral[900],
68
+ borders.color.neutral[700],
67
69
  borders.width.thin,
68
70
  r.lg,
69
- p[4],
71
+ p[8],
70
72
  { maxWidth: 700, width: "100%" },
71
73
  ], children: (0, jsx_runtime_1.jsx)(Problems, { probs: problems, onIgnore: () => setDismiss(true) }) }) }))] }));
72
- };
73
- exports.ProblemsWrapper = ProblemsWrapper;
74
+ });
74
75
  exports.default = Problems;
@@ -18,12 +18,16 @@ function Player(props) {
18
18
  const setIngest = (0, player_store_1.usePlayerStore)((x) => x.setIngestConnectionState);
19
19
  const clearControlsTimeout = (0, player_store_1.usePlayerStore)((x) => x.clearControlsTimeout);
20
20
  const setReportingURL = (0, player_store_1.usePlayerStore)((x) => x.setReportingURL);
21
+ const setEmbedded = (0, player_store_1.usePlayerStore)((x) => x.setEmbedded);
21
22
  const reportModalOpen = (0, player_store_1.usePlayerStore)((x) => x.reportModalOpen);
22
23
  const setReportModalOpen = (0, player_store_1.usePlayerStore)((x) => x.setReportModalOpen);
23
24
  const reportSubject = (0, player_store_1.usePlayerStore)((x) => x.reportSubject);
24
25
  (0, react_1.useEffect)(() => {
25
26
  setReportingURL(props.reportingURL ?? null);
26
27
  }, [props.reportingURL]);
28
+ (0, react_1.useEffect)(() => {
29
+ setEmbedded(props.embedded ?? false);
30
+ }, [props.embedded]);
27
31
  // Will call back every few seconds to send health updates
28
32
  usePlayerStatus();
29
33
  (0, react_1.useEffect)(() => {
@@ -47,6 +47,7 @@ const ReportModal = ({ open, onOpenChange, onSubmit, subject, title = "Report",
47
47
  const [additionalComments, setAdditionalComments] = (0, react_1.useState)("");
48
48
  const [isSubmitting, setIsSubmitting] = (0, react_1.useState)(false);
49
49
  const [submitError, setSubmitError] = (0, react_1.useState)(null);
50
+ const { theme } = (0, ui_1.useTheme)();
50
51
  const submitReport = (0, livestream_store_1.useSubmitReport)();
51
52
  const handleCancel = () => {
52
53
  setSelectedReason(null);
@@ -74,7 +75,7 @@ const ReportModal = ({ open, onOpenChange, onSubmit, subject, title = "Report",
74
75
  setIsSubmitting(false);
75
76
  }
76
77
  };
77
- return ((0, jsx_runtime_1.jsxs)(ui_1.Dialog, { open: open, onOpenChange: onOpenChange, title: title, description: description, showCloseButton: true, variant: "default", size: "md", dismissible: false, position: "center", children: [(0, jsx_runtime_1.jsxs)(ui_1.ModalContent, { style: [__1.zero.pb[2]], children: [REPORT_REASONS.map((reason) => ((0, jsx_runtime_1.jsxs)(react_native_1.TouchableOpacity, { onPress: () => setSelectedReason(reason.value), style: [
78
+ return ((0, jsx_runtime_1.jsxs)(ui_1.ResponsiveDialog, { open: open, onOpenChange: onOpenChange, title: title, description: description, showCloseButton: true, variant: "default", size: "md", dismissible: false, position: "center", children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [__1.zero.pb[2]], children: [REPORT_REASONS.map((reason) => ((0, jsx_runtime_1.jsxs)(react_native_1.TouchableOpacity, { onPress: () => setSelectedReason(reason.value), style: [
78
79
  __1.zero.layout.flex.row,
79
80
  __1.zero.gap.all[2],
80
81
  __1.zero.py[3],
@@ -84,7 +85,7 @@ const ReportModal = ({ open, onOpenChange, onSubmit, subject, title = "Report",
84
85
  selectedReason === reason.value && {
85
86
  backgroundColor: "rgba(0, 122, 255, 0.1)",
86
87
  },
87
- ], children: [(0, jsx_runtime_1.jsx)(react_native_1.View, { children: selectedReason === reason.value ? (0, jsx_runtime_1.jsx)(lucide_react_native_1.CheckCircle, {}) : (0, jsx_runtime_1.jsx)(lucide_react_native_1.Circle, {}) }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [__1.zero.layout.flex.column, __1.zero.gap.all[1], __1.zero.flex[1]], children: [(0, jsx_runtime_1.jsx)(ui_1.Text, { style: [{ fontWeight: "600" }], children: reason.label }), (0, jsx_runtime_1.jsx)(ui_1.Text, { style: [{ fontSize: 14, color: "rgba(255,255,255,0.7)" }], children: reason.description })] })] }, reason.value))), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [__1.zero.pb[4], __1.zero.mt[4], __1.zero.px[2]], children: [(0, jsx_runtime_1.jsx)(ui_1.Text, { style: [__1.zero.mb[2]], children: "Additional Comments (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.Textarea, { maxLength: 500, numberOfLines: 3, value: additionalComments, onChangeText: setAdditionalComments, placeholder: "Provide additional context for this report..." }), submitError && ((0, jsx_runtime_1.jsx)(ui_1.Text, { style: [__1.zero.mt[2], { color: "red", fontSize: 14 }], children: submitError }))] })] }), (0, jsx_runtime_1.jsxs)(ui_1.DialogFooter, { children: [(0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "secondary", onPress: handleCancel, disabled: isSubmitting, children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "primary", onPress: handleSubmit, disabled: !selectedReason || isSubmitting, children: isSubmitting ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Loader2, { style: [{ marginRight: 8 }] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Submitting..." })] })) : ((0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Submit" })) })] })] }));
88
+ ], children: [(0, jsx_runtime_1.jsx)(react_native_1.View, { children: selectedReason === reason.value ? ((0, jsx_runtime_1.jsx)(lucide_react_native_1.CheckCircle, { color: theme.colors.foreground })) : ((0, jsx_runtime_1.jsx)(lucide_react_native_1.Circle, { color: theme.colors.foreground })) }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [__1.zero.layout.flex.column, __1.zero.gap.all[1], __1.zero.flex[1]], children: [(0, jsx_runtime_1.jsx)(ui_1.Text, { style: [{ fontWeight: "600" }], children: reason.label }), (0, jsx_runtime_1.jsx)(ui_1.Text, { style: [{ fontSize: 14, color: "rgba(255,255,255,0.7)" }], children: reason.description })] })] }, reason.value))), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [__1.zero.pb[4], __1.zero.mt[4], __1.zero.px[2]], children: [(0, jsx_runtime_1.jsx)(ui_1.Text, { style: [__1.zero.mb[2]], children: "Additional Comments (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.Textarea, { maxLength: 500, numberOfLines: 3, value: additionalComments, onChangeText: setAdditionalComments, placeholder: "Provide additional context for this report..." }), submitError && ((0, jsx_runtime_1.jsx)(ui_1.Text, { style: [__1.zero.mt[2], { color: "red", fontSize: 14 }], children: submitError }))] })] }), (0, jsx_runtime_1.jsxs)(ui_1.DialogFooter, { children: [(0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "secondary", onPress: handleCancel, disabled: isSubmitting, children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "primary", onPress: handleSubmit, disabled: !selectedReason || isSubmitting, children: isSubmitting ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Loader2, { style: [{ marginRight: 8 }] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Submitting..." })] })) : ((0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Submit" })) })] })] }));
88
89
  };
89
90
  exports.ReportModal = ReportModal;
90
91
  exports.default = exports.ReportModal;
@@ -6,9 +6,11 @@ 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
8
  const react_native_1 = require("react-native");
9
+ const __1 = require("../../..");
9
10
  const theme_1 = require("../../../lib/theme");
10
11
  const livestream_store_1 = require("../../../livestream-store");
11
12
  const player_store_1 = require("../../../player-store/");
13
+ const graph_1 = require("../../../streamplace-store/graph");
12
14
  const ui_1 = require("../../ui");
13
15
  function ContextMenu({ dropdownPortalContainer, }) {
14
16
  const quality = (0, player_store_1.usePlayerStore)((x) => x.selectedRendition);
@@ -21,6 +23,10 @@ function ContextMenu({ dropdownPortalContainer, }) {
21
23
  const livestream = (0, livestream_store_1.useLivestreamStore)((x) => x.livestream);
22
24
  const setReportModalOpen = (0, player_store_1.usePlayerStore)((x) => x.setReportModalOpen);
23
25
  const setReportSubject = (0, player_store_1.usePlayerStore)((x) => x.setReportSubject);
26
+ const { profile } = (0, __1.useLivestreamInfo)();
27
+ const avatars = (0, __1.useAvatars)(profile?.did ? [profile?.did] : []);
28
+ const ls = (0, livestream_store_1.useLivestreamStore)((x) => x.livestream);
29
+ let graphManager = (0, graph_1.useGraphManager)(profile?.did);
24
30
  const lowLatency = protocol === "webrtc";
25
31
  const setLowLatency = (value) => {
26
32
  setProtocol(value ? player_store_1.PlayerProtocol.WEBRTC : player_store_1.PlayerProtocol.HLS);
@@ -33,7 +39,44 @@ function ContextMenu({ dropdownPortalContainer, }) {
33
39
  const DropdownMenuContent = isMobile
34
40
  ? ui_1.ResponsiveDropdownMenuContent
35
41
  : 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.Menu, { 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 }) })] }) })] }));
42
+ 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.Menu, { 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: [react_native_1.Platform.OS !== "web" && ((0, jsx_runtime_1.jsxs)(ui_1.DropdownMenuGroup, { title: "Streamer", children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
43
+ __1.zero.layout.flex.row,
44
+ __1.zero.layout.flex.center,
45
+ __1.zero.gap.all[3],
46
+ { flex: 1, minWidth: 0 },
47
+ ], children: [profile?.did && avatars[profile?.did]?.avatar && ((0, jsx_runtime_1.jsx)(react_native_1.Image, { source: {
48
+ uri: avatars[profile?.did]?.avatar,
49
+ }, style: { width: 42, height: 42, borderRadius: 999 }, resizeMode: "cover" }, "avatar")), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flex: 1, minWidth: 0 }, children: [(0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
50
+ __1.zero.layout.flex.row,
51
+ __1.zero.layout.flex.alignCenter,
52
+ __1.zero.gap.all[2],
53
+ ], children: (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: () => {
54
+ if (profile?.handle) {
55
+ const url = `https://bsky.app/profile/${profile.handle}`;
56
+ react_native_1.Linking.openURL(url);
57
+ }
58
+ }, children: (0, jsx_runtime_1.jsxs)(ui_1.Text, { children: ["@", profile?.handle || "user"] }) }) }), (0, jsx_runtime_1.jsx)(ui_1.Text, { color: "muted", size: "sm", numberOfLines: 2, ellipsizeMode: "tail", children: ls?.record.title || "Stream Title" })] })] }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuSeparator, {}), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { disabled: graphManager.isLoading || !profile?.did, onPress: async () => {
59
+ try {
60
+ if (graphManager.isFollowing) {
61
+ await graphManager.unfollow();
62
+ }
63
+ else {
64
+ await graphManager.follow();
65
+ }
66
+ }
67
+ catch (err) {
68
+ console.error("Follow/unfollow error:", err);
69
+ }
70
+ }, children: (0, jsx_runtime_1.jsx)(ui_1.Text, { color: graphManager.isFollowing ? "destructive" : "default", children: graphManager.isLoading
71
+ ? "Loading..."
72
+ : graphManager.isFollowing
73
+ ? "Unfollow"
74
+ : "Follow" }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuSeparator, {}), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: () => {
75
+ if (profile?.handle) {
76
+ const url = `https://bsky.app/profile/${profile.handle}`;
77
+ react_native_1.Linking.openURL(url);
78
+ }
79
+ }, children: (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "View Profile on Bluesky" }) })] })), (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 }) })] }) })] }));
37
80
  }
38
81
  function ReportButton({ livestream, setReportModalOpen, setReportSubject, }) {
39
82
  const { onOpenChange } = (0, dropdown_menu_1.useRootContext)();
@@ -85,7 +85,7 @@ exports.Button = (0, react_1.forwardRef)(({ variant = "primary", size = "md", ch
85
85
  { borderRadius: zero.borderRadius.md },
86
86
  ],
87
87
  inner: { gap: 4 },
88
- text: zt.text.sm,
88
+ text: zero.typography.universal.sm,
89
89
  };
90
90
  case "lg":
91
91
  return {
@@ -94,8 +94,8 @@ exports.Button = (0, react_1.forwardRef)(({ variant = "primary", size = "md", ch
94
94
  zero.py[3],
95
95
  { borderRadius: zero.borderRadius.md },
96
96
  ],
97
- inner: { gap: 8 },
98
- text: zt.text.lg,
97
+ inner: { gap: 12 },
98
+ text: zero.typography.universal.lg,
99
99
  };
100
100
  case "xl":
101
101
  return {
@@ -105,17 +105,17 @@ exports.Button = (0, react_1.forwardRef)(({ variant = "primary", size = "md", ch
105
105
  { borderRadius: zero.borderRadius.lg },
106
106
  ],
107
107
  inner: { gap: 12 },
108
- text: zt.text.xl,
108
+ text: zero.typography.universal.xl,
109
109
  };
110
110
  case "pill":
111
111
  return {
112
112
  button: [
113
- zero.px[4],
114
- zero.py[2],
113
+ zero.px[2],
114
+ zero.py[1],
115
115
  { borderRadius: zero.borderRadius.full },
116
116
  ],
117
117
  inner: { gap: 4 },
118
- text: zt.text.sm,
118
+ text: zero.typography.universal.xs,
119
119
  };
120
120
  case "md":
121
121
  default:
@@ -126,7 +126,7 @@ exports.Button = (0, react_1.forwardRef)(({ variant = "primary", size = "md", ch
126
126
  { borderRadius: zero.borderRadius.md },
127
127
  ],
128
128
  inner: { gap: 6 },
129
- text: zt.text.md,
129
+ text: zero.typography.universal.sm,
130
130
  };
131
131
  }
132
132
  }, [size, zt]);
@@ -170,6 +170,6 @@ exports.Button = (0, react_1.forwardRef)(({ variant = "primary", size = "md", ch
170
170
  return icons.color.default;
171
171
  }
172
172
  }, [variant, icons]);
173
- return ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Root, { ref: ref, disabled: disabled || loading, style: [buttonStyle, sizeStyles.button, style], ...props, children: (0, jsx_runtime_1.jsxs)(button_1.ButtonPrimitive.Content, { style: sizeStyles.inner, children: [loading && !leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", style: { width: iconSize, height: iconSize }, children: leftIcon })) : null, (0, jsx_runtime_1.jsx)(text_1.TextPrimitive.Root, { style: [textStyle, sizeStyles.text], children: loading && loadingText ? loadingText : children }), loading && rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", style: { width: iconSize, height: iconSize }, children: rightIcon })) : null] }) }));
173
+ return ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Root, { ref: ref, disabled: disabled || loading, style: [buttonStyle, sizeStyles.button, style], ...props, children: (0, jsx_runtime_1.jsxs)(button_1.ButtonPrimitive.Content, { style: sizeStyles.inner, children: [loading && !leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", children: leftIcon })) : null, (0, jsx_runtime_1.jsx)(text_1.TextPrimitive.Root, { style: [textStyle, sizeStyles.text], children: loading && loadingText ? loadingText : children }), loading && rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", style: { width: iconSize, height: iconSize }, children: rightIcon })) : null] }) }));
174
174
  });
175
175
  exports.Button.displayName = "Button";
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Checkbox = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const lucide_react_native_1 = require("lucide-react-native");
6
+ const react_1 = require("react");
7
+ const react_native_1 = require("react-native");
8
+ const theme_1 = require("../../lib/theme/theme");
9
+ const text_1 = require("./text");
10
+ exports.Checkbox = (0, react_1.forwardRef)(({ checked, onCheckedChange, disabled = false, size = "md", label, description, style, ...props }, ref) => {
11
+ const { theme } = (0, theme_1.useTheme)();
12
+ const handlePress = () => {
13
+ if (!disabled) {
14
+ onCheckedChange(!checked);
15
+ }
16
+ };
17
+ const styles = createStyles(theme, size, disabled, checked);
18
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.TouchableOpacity, { ref: ref, style: [styles.container, style], onPress: handlePress, disabled: disabled, ...props, children: [(0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.checkbox, children: checked && ((0, jsx_runtime_1.jsx)(lucide_react_native_1.Check, { size: size === "sm" ? 12 : size === "lg" ? 18 : 14, color: disabled
19
+ ? theme.colors.textDisabled
20
+ : theme.colors.primaryForeground })) }), (label || description) && ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.content, children: [label && (0, jsx_runtime_1.jsx)(text_1.Text, { style: styles.label, children: label }), description && ((0, jsx_runtime_1.jsx)(text_1.Text, { style: styles.description, children: description }))] }))] }));
21
+ });
22
+ exports.Checkbox.displayName = "Checkbox";
23
+ function createStyles(theme, size, disabled, checked) {
24
+ const sizeStyles = {
25
+ sm: {
26
+ checkboxSize: 16,
27
+ borderRadius: 2,
28
+ padding: theme.spacing[1],
29
+ gap: theme.spacing[1],
30
+ },
31
+ md: {
32
+ checkboxSize: 20,
33
+ borderRadius: 4,
34
+ padding: theme.spacing[1],
35
+ gap: theme.spacing[2],
36
+ },
37
+ lg: {
38
+ checkboxSize: 24,
39
+ borderRadius: 6,
40
+ padding: theme.spacing[2],
41
+ gap: theme.spacing[3],
42
+ },
43
+ };
44
+ const currentSize = sizeStyles[size];
45
+ return react_native_1.StyleSheet.create({
46
+ container: {
47
+ flexDirection: "row",
48
+ alignItems: "flex-start",
49
+ opacity: disabled ? 0.5 : 1,
50
+ },
51
+ checkbox: {
52
+ width: currentSize.checkboxSize,
53
+ height: currentSize.checkboxSize,
54
+ borderWidth: 1.5,
55
+ borderColor: disabled
56
+ ? theme.colors.border
57
+ : checked
58
+ ? theme.colors.primary
59
+ : theme.colors.border,
60
+ borderRadius: currentSize.borderRadius,
61
+ backgroundColor: disabled
62
+ ? theme.colors.muted
63
+ : checked
64
+ ? theme.colors.primary
65
+ : "transparent",
66
+ alignItems: "center",
67
+ justifyContent: "center",
68
+ },
69
+ content: {
70
+ flex: 1,
71
+ paddingTop: currentSize.padding * 0.5,
72
+ paddingLeft: theme.spacing[2],
73
+ },
74
+ label: {
75
+ fontSize: size === "sm" ? 14 : size === "lg" ? 18 : 16,
76
+ fontWeight: "500",
77
+ color: disabled ? theme.colors.textDisabled : theme.colors.text,
78
+ lineHeight: size === "sm" ? 18 : size === "lg" ? 22 : 20,
79
+ },
80
+ description: {
81
+ fontSize: size === "sm" ? 12 : size === "lg" ? 16 : 14,
82
+ color: disabled ? theme.colors.textDisabled : theme.colors.textMuted,
83
+ marginTop: theme.spacing[1],
84
+ lineHeight: size === "sm" ? 16 : size === "lg" ? 20 : 18,
85
+ },
86
+ });
87
+ }