@streamplace/components 0.8.6 → 0.8.9
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/content-metadata/content-metadata-form.js +6 -22
- package/dist/components/content-metadata/content-rights.js +18 -47
- package/dist/components/content-metadata/content-warning-badge.js +42 -0
- package/dist/components/content-metadata/content-warnings.js +15 -48
- package/dist/components/content-metadata/index.js +3 -1
- package/dist/components/mobile-player/ui/viewer-context-menu.js +20 -13
- package/dist/components/ui/checkbox.js +6 -18
- package/dist/components/ui/dropdown.js +238 -26
- package/dist/components/ui/primitives/text.js +19 -4
- package/dist/components/ui/select.js +44 -75
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +2 -2
- package/src/components/content-metadata/content-metadata-form.tsx +9 -49
- package/src/components/content-metadata/content-rights.tsx +31 -56
- package/src/components/content-metadata/content-warning-badge.tsx +94 -0
- package/src/components/content-metadata/content-warnings.tsx +46 -58
- package/src/components/content-metadata/index.tsx +2 -0
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +81 -26
- package/src/components/ui/checkbox.tsx +23 -21
- package/src/components/ui/dropdown.tsx +445 -75
- package/src/components/ui/primitives/text.tsx +24 -4
- package/src/components/ui/select.tsx +97 -125
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { forwardRef } from "react";
|
|
2
|
-
import { StyleSheet
|
|
1
|
+
import { forwardRef, type ComponentProps } from "react";
|
|
2
|
+
import { StyleSheet } from "react-native";
|
|
3
|
+
import { useTheme, zero } from "../..";
|
|
3
4
|
import { LICENSE_URL_LABELS } from "../../lib/metadata-constants";
|
|
4
|
-
import { useTheme } from "../../lib/theme/theme";
|
|
5
5
|
import { Text } from "../ui/text";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const { layout, gap, mt, text: textStyles } = zero;
|
|
8
|
+
|
|
9
|
+
export interface ContentRightsProps extends ComponentProps<typeof Text> {
|
|
8
10
|
contentRights: {
|
|
9
11
|
creator?: string;
|
|
10
12
|
copyrightNotice?: string;
|
|
@@ -15,16 +17,13 @@ export interface ContentRightsProps {
|
|
|
15
17
|
compact?: boolean;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
export const ContentRights = forwardRef<
|
|
19
|
-
({ contentRights }, ref) => {
|
|
20
|
-
const {
|
|
21
|
-
|
|
20
|
+
export const ContentRights = forwardRef<Text, ContentRightsProps>(
|
|
21
|
+
({ contentRights, compact, ...rest }, ref) => {
|
|
22
|
+
const { zero } = useTheme();
|
|
22
23
|
if (!contentRights || Object.keys(contentRights).length === 0) {
|
|
23
24
|
return null;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
const styles = createStyles(theme);
|
|
27
|
-
|
|
28
27
|
const formatLicense = (license: string) => {
|
|
29
28
|
return LICENSE_URL_LABELS[license] || license;
|
|
30
29
|
};
|
|
@@ -38,7 +37,11 @@ export const ContentRights = forwardRef<any, ContentRightsProps>(
|
|
|
38
37
|
// }
|
|
39
38
|
|
|
40
39
|
if (contentRights.copyrightYear) {
|
|
41
|
-
elements.push(
|
|
40
|
+
elements.push(
|
|
41
|
+
`© ${contentRights.copyrightYear.toString()}${contentRights.creditLine ? " " + contentRights.creditLine : ""}`,
|
|
42
|
+
);
|
|
43
|
+
} else if (contentRights.creditLine) {
|
|
44
|
+
elements.push(contentRights.creditLine);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
if (contentRights.license) {
|
|
@@ -49,56 +52,28 @@ export const ContentRights = forwardRef<any, ContentRightsProps>(
|
|
|
49
52
|
elements.push(contentRights.copyrightNotice);
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
if (
|
|
53
|
-
elements
|
|
55
|
+
if (elements.length > 0) {
|
|
56
|
+
elements[0] = "Stream content is " + elements[0];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (elements.length == 0) {
|
|
60
|
+
return null;
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
return (
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
<Text
|
|
65
|
+
ref={ref}
|
|
66
|
+
style={[
|
|
67
|
+
zero.text.mutedForeground,
|
|
68
|
+
mt[1],
|
|
69
|
+
StyleSheet.flatten(rest.style),
|
|
70
|
+
]}
|
|
71
|
+
{...rest}
|
|
72
|
+
>
|
|
73
|
+
{elements.join(" • ")}
|
|
74
|
+
</Text>
|
|
60
75
|
);
|
|
61
76
|
},
|
|
62
77
|
);
|
|
63
78
|
|
|
64
79
|
ContentRights.displayName = "ContentRights";
|
|
65
|
-
|
|
66
|
-
function createStyles(theme: any) {
|
|
67
|
-
return StyleSheet.create({
|
|
68
|
-
container: {
|
|
69
|
-
paddingVertical: theme.spacing[3],
|
|
70
|
-
},
|
|
71
|
-
title: {
|
|
72
|
-
fontSize: 14,
|
|
73
|
-
fontWeight: "600",
|
|
74
|
-
color: theme.colors.text,
|
|
75
|
-
marginBottom: theme.spacing[2],
|
|
76
|
-
},
|
|
77
|
-
content: {
|
|
78
|
-
gap: theme.spacing[2],
|
|
79
|
-
},
|
|
80
|
-
row: {
|
|
81
|
-
flexDirection: "row",
|
|
82
|
-
gap: theme.spacing[2],
|
|
83
|
-
},
|
|
84
|
-
label: {
|
|
85
|
-
fontSize: 13,
|
|
86
|
-
color: theme.colors.textMuted,
|
|
87
|
-
},
|
|
88
|
-
value: {
|
|
89
|
-
fontSize: 13,
|
|
90
|
-
color: theme.colors.text,
|
|
91
|
-
},
|
|
92
|
-
compactContainer: {
|
|
93
|
-
flexDirection: "row",
|
|
94
|
-
gap: theme.spacing[2],
|
|
95
|
-
flexWrap: "wrap",
|
|
96
|
-
marginTop: theme.spacing[1],
|
|
97
|
-
},
|
|
98
|
-
compactText: {
|
|
99
|
-
fontSize: 14,
|
|
100
|
-
fontWeight: "500",
|
|
101
|
-
color: theme.colors.text,
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { AlertTriangle, ChevronDown } from "lucide-react-native";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { zero } from "../..";
|
|
4
|
+
import { C2PA_WARNING_LABELS } from "../../lib/metadata-constants";
|
|
5
|
+
import { useTheme } from "../../lib/theme/theme";
|
|
6
|
+
import { pt, r } from "../../ui";
|
|
7
|
+
import {
|
|
8
|
+
DropdownMenu,
|
|
9
|
+
DropdownMenuTrigger,
|
|
10
|
+
ResponsiveDropdownMenuContent,
|
|
11
|
+
} from "../ui/dropdown";
|
|
12
|
+
import { Text } from "../ui/text";
|
|
13
|
+
|
|
14
|
+
const { px, py, gap, layout } = zero;
|
|
15
|
+
|
|
16
|
+
export interface ContentWarningBadgeProps {
|
|
17
|
+
warnings: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function ContentWarningBadge({ warnings }: ContentWarningBadgeProps) {
|
|
21
|
+
const { theme } = useTheme();
|
|
22
|
+
|
|
23
|
+
const getWarningLabel = (warning: string): string => {
|
|
24
|
+
return C2PA_WARNING_LABELS[warning] || warning;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
if (!warnings || warnings.length === 0) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<DropdownMenu>
|
|
33
|
+
<DropdownMenuTrigger>
|
|
34
|
+
<View
|
|
35
|
+
style={[
|
|
36
|
+
layout.flex.row,
|
|
37
|
+
layout.flex.align.center,
|
|
38
|
+
gap.all[2],
|
|
39
|
+
px[3],
|
|
40
|
+
py[2],
|
|
41
|
+
r.md,
|
|
42
|
+
{ backgroundColor: theme.colors.warning + "20" },
|
|
43
|
+
]}
|
|
44
|
+
>
|
|
45
|
+
<AlertTriangle size={14} color={theme.colors.warningForeground} />
|
|
46
|
+
<Text
|
|
47
|
+
size="sm"
|
|
48
|
+
weight="semibold"
|
|
49
|
+
style={{ color: theme.colors.warningForeground }}
|
|
50
|
+
>
|
|
51
|
+
Intended for certain audiences
|
|
52
|
+
</Text>
|
|
53
|
+
<ChevronDown size={14} color={theme.colors.warningForeground} />
|
|
54
|
+
</View>
|
|
55
|
+
</DropdownMenuTrigger>
|
|
56
|
+
|
|
57
|
+
<ResponsiveDropdownMenuContent>
|
|
58
|
+
<View style={[layout.flex.column, px[2], pt[2]]}>
|
|
59
|
+
<Text>Heads up!</Text>
|
|
60
|
+
<Text>This stream may contain:</Text>
|
|
61
|
+
</View>
|
|
62
|
+
<View
|
|
63
|
+
style={[
|
|
64
|
+
layout.flex.row,
|
|
65
|
+
{ flexWrap: "wrap" },
|
|
66
|
+
gap.all[2],
|
|
67
|
+
px[2],
|
|
68
|
+
py[2],
|
|
69
|
+
]}
|
|
70
|
+
>
|
|
71
|
+
{warnings.map((warning, index) => (
|
|
72
|
+
<View
|
|
73
|
+
key={index}
|
|
74
|
+
style={[
|
|
75
|
+
{ backgroundColor: theme.colors.warning },
|
|
76
|
+
px[3],
|
|
77
|
+
py[1],
|
|
78
|
+
r.full,
|
|
79
|
+
]}
|
|
80
|
+
>
|
|
81
|
+
<Text
|
|
82
|
+
size="sm"
|
|
83
|
+
weight="semibold"
|
|
84
|
+
style={{ color: theme.colors.warningForeground }}
|
|
85
|
+
>
|
|
86
|
+
{getWarningLabel(warning)}
|
|
87
|
+
</Text>
|
|
88
|
+
</View>
|
|
89
|
+
))}
|
|
90
|
+
</View>
|
|
91
|
+
</ResponsiveDropdownMenuContent>
|
|
92
|
+
</DropdownMenu>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -1,34 +1,50 @@
|
|
|
1
1
|
import { forwardRef } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { zero } from "../..";
|
|
3
4
|
import { C2PA_WARNING_LABELS } from "../../lib/metadata-constants";
|
|
4
5
|
import { useTheme } from "../../lib/theme/theme";
|
|
5
6
|
import { Text } from "../ui/text";
|
|
6
7
|
|
|
8
|
+
const { layout, gap, bg, r, p, px, py, text: textStyles, borders } = zero;
|
|
9
|
+
|
|
7
10
|
export interface ContentWarningsProps {
|
|
8
11
|
warnings: string[];
|
|
9
12
|
compact?: boolean;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
export const ContentWarnings = forwardRef<
|
|
13
|
-
({ warnings, compact = false }, ref) => {
|
|
15
|
+
export const ContentWarnings = forwardRef<View, ContentWarningsProps>(
|
|
16
|
+
({ warnings, compact = false, ...rest }, ref) => {
|
|
14
17
|
const { theme } = useTheme();
|
|
15
18
|
|
|
16
19
|
if (!warnings || warnings.length === 0) {
|
|
17
20
|
return null;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
const styles = createStyles(theme, compact);
|
|
21
|
-
|
|
22
23
|
const getWarningLabel = (warning: string): string => {
|
|
23
24
|
return C2PA_WARNING_LABELS[warning] || warning;
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
if (compact) {
|
|
27
28
|
return (
|
|
28
|
-
<View
|
|
29
|
+
<View
|
|
30
|
+
ref={ref}
|
|
31
|
+
style={[layout.flex.row, layout.flex.wrap.wrap, gap.all[1]]}
|
|
32
|
+
{...rest}
|
|
33
|
+
>
|
|
29
34
|
{warnings.map((warning, index) => (
|
|
30
|
-
<View
|
|
31
|
-
|
|
35
|
+
<View
|
|
36
|
+
key={index}
|
|
37
|
+
style={[
|
|
38
|
+
{ backgroundColor: theme.colors.warning },
|
|
39
|
+
r.full,
|
|
40
|
+
px[2],
|
|
41
|
+
{ paddingVertical: 2 },
|
|
42
|
+
]}
|
|
43
|
+
>
|
|
44
|
+
<Text
|
|
45
|
+
size="sm"
|
|
46
|
+
style={[{ color: theme.colors.warningForeground }]}
|
|
47
|
+
>
|
|
32
48
|
{getWarningLabel(warning)}
|
|
33
49
|
</Text>
|
|
34
50
|
</View>
|
|
@@ -38,12 +54,29 @@ export const ContentWarnings = forwardRef<any, ContentWarningsProps>(
|
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
return (
|
|
41
|
-
<View ref={ref} style={
|
|
42
|
-
<Text
|
|
43
|
-
|
|
57
|
+
<View ref={ref} style={[layout.flex.column, gap.all[2]]} {...rest}>
|
|
58
|
+
<Text
|
|
59
|
+
style={[{ fontSize: 14, fontWeight: "600" }, textStyles.gray[900]]}
|
|
60
|
+
>
|
|
61
|
+
Content Warnings
|
|
62
|
+
</Text>
|
|
63
|
+
<View style={[layout.flex.row, layout.flex.wrap.wrap, gap.all[2]]}>
|
|
44
64
|
{warnings.map((warning, index) => (
|
|
45
|
-
<View
|
|
46
|
-
|
|
65
|
+
<View
|
|
66
|
+
key={index}
|
|
67
|
+
style={[
|
|
68
|
+
{ backgroundColor: theme.colors.warning },
|
|
69
|
+
r.full,
|
|
70
|
+
px[3],
|
|
71
|
+
py[1],
|
|
72
|
+
]}
|
|
73
|
+
>
|
|
74
|
+
<Text
|
|
75
|
+
size="sm"
|
|
76
|
+
style={[{ color: theme.colors.warningForeground }]}
|
|
77
|
+
>
|
|
78
|
+
{getWarningLabel(warning)}
|
|
79
|
+
</Text>
|
|
47
80
|
</View>
|
|
48
81
|
))}
|
|
49
82
|
</View>
|
|
@@ -53,48 +86,3 @@ export const ContentWarnings = forwardRef<any, ContentWarningsProps>(
|
|
|
53
86
|
);
|
|
54
87
|
|
|
55
88
|
ContentWarnings.displayName = "ContentWarnings";
|
|
56
|
-
|
|
57
|
-
function createStyles(theme: any, compact: boolean) {
|
|
58
|
-
return StyleSheet.create({
|
|
59
|
-
container: {
|
|
60
|
-
flexDirection: "column",
|
|
61
|
-
gap: theme.spacing[2],
|
|
62
|
-
},
|
|
63
|
-
title: {
|
|
64
|
-
fontSize: 14,
|
|
65
|
-
fontWeight: "600",
|
|
66
|
-
color: theme.colors.text,
|
|
67
|
-
},
|
|
68
|
-
warningsContainer: {
|
|
69
|
-
flexDirection: "row",
|
|
70
|
-
flexWrap: "wrap",
|
|
71
|
-
gap: theme.spacing[2],
|
|
72
|
-
},
|
|
73
|
-
warning: {
|
|
74
|
-
backgroundColor: theme.colors.warning,
|
|
75
|
-
borderRadius: theme.borderRadius.md,
|
|
76
|
-
padding: theme.spacing[2],
|
|
77
|
-
},
|
|
78
|
-
warningText: {
|
|
79
|
-
color: theme.colors.warningForeground,
|
|
80
|
-
fontSize: 12,
|
|
81
|
-
fontWeight: "500",
|
|
82
|
-
},
|
|
83
|
-
compactContainer: {
|
|
84
|
-
flexDirection: "row",
|
|
85
|
-
flexWrap: "wrap",
|
|
86
|
-
gap: theme.spacing[1],
|
|
87
|
-
},
|
|
88
|
-
compactWarning: {
|
|
89
|
-
backgroundColor: theme.colors.warning,
|
|
90
|
-
borderRadius: theme.borderRadius.full,
|
|
91
|
-
paddingHorizontal: 10,
|
|
92
|
-
paddingVertical: 4,
|
|
93
|
-
},
|
|
94
|
-
compactWarningText: {
|
|
95
|
-
color: theme.colors.warningForeground,
|
|
96
|
-
fontSize: 14,
|
|
97
|
-
fontWeight: "600",
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
}
|
|
@@ -3,8 +3,10 @@ export { ContentMetadataForm } from "./content-metadata-form";
|
|
|
3
3
|
|
|
4
4
|
// Display components
|
|
5
5
|
export { ContentRights } from "./content-rights";
|
|
6
|
+
export { ContentWarningBadge } from "./content-warning-badge";
|
|
6
7
|
export { ContentWarnings } from "./content-warnings";
|
|
7
8
|
|
|
8
9
|
export type { ContentRightsProps } from "./content-rights";
|
|
9
10
|
|
|
11
|
+
export type { ContentWarningBadgeProps } from "./content-warning-badge";
|
|
10
12
|
export type { ContentWarningsProps } from "./content-warnings";
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { useRootContext } from "@rn-primitives/dropdown-menu";
|
|
2
2
|
import { Menu } from "lucide-react-native";
|
|
3
3
|
import { Image, Linking, Platform, Pressable, View } from "react-native";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ContentRights,
|
|
6
|
+
ContentWarnings,
|
|
7
|
+
useAvatars,
|
|
8
|
+
useLivestreamInfo,
|
|
9
|
+
zero,
|
|
10
|
+
} from "../../..";
|
|
5
11
|
import { colors } from "../../../lib/theme";
|
|
6
12
|
import { useLivestreamStore } from "../../../livestream-store";
|
|
7
13
|
import { PlayerProtocol, usePlayerStore } from "../../../player-store/";
|
|
8
14
|
import { useGraphManager } from "../../../streamplace-store/graph";
|
|
15
|
+
import { gap, pt, px } from "../../../ui";
|
|
9
16
|
import {
|
|
10
17
|
DropdownMenu,
|
|
11
18
|
DropdownMenuCheckboxItem,
|
|
12
|
-
DropdownMenuContentWithoutPortal,
|
|
13
19
|
DropdownMenuGroup,
|
|
14
20
|
DropdownMenuInfo,
|
|
15
21
|
DropdownMenuItem,
|
|
@@ -17,6 +23,9 @@ import {
|
|
|
17
23
|
DropdownMenuRadioGroup,
|
|
18
24
|
DropdownMenuRadioItem,
|
|
19
25
|
DropdownMenuSeparator,
|
|
26
|
+
DropdownMenuSub,
|
|
27
|
+
DropdownMenuSubContent,
|
|
28
|
+
DropdownMenuSubTrigger,
|
|
20
29
|
DropdownMenuTrigger,
|
|
21
30
|
ResponsiveDropdownMenuContent,
|
|
22
31
|
Text,
|
|
@@ -42,8 +51,14 @@ export function ContextMenu({
|
|
|
42
51
|
const setReportSubject = usePlayerStore((x) => x.setReportSubject);
|
|
43
52
|
|
|
44
53
|
const { profile } = useLivestreamInfo();
|
|
54
|
+
|
|
45
55
|
const avatars = useAvatars(profile?.did ? [profile?.did] : []);
|
|
46
56
|
const ls = useLivestreamStore((x) => x.livestream);
|
|
57
|
+
const segment = useLivestreamStore((x) => x.segment);
|
|
58
|
+
|
|
59
|
+
// Get content rights from the latest segment
|
|
60
|
+
const contentRights = segment?.contentRights;
|
|
61
|
+
const contentWarnings = segment?.contentWarnings?.warnings || [];
|
|
47
62
|
|
|
48
63
|
let graphManager = useGraphManager(profile?.did);
|
|
49
64
|
|
|
@@ -58,10 +73,7 @@ export function ContextMenu({
|
|
|
58
73
|
// dummy portal for mobile
|
|
59
74
|
const Portal = isMobile ? View : DropdownMenuPortal;
|
|
60
75
|
|
|
61
|
-
|
|
62
|
-
const DropdownMenuContent = isMobile
|
|
63
|
-
? ResponsiveDropdownMenuContent
|
|
64
|
-
: DropdownMenuContentWithoutPortal;
|
|
76
|
+
const DropdownMenuContent = ResponsiveDropdownMenuContent;
|
|
65
77
|
|
|
66
78
|
return (
|
|
67
79
|
<DropdownMenu>
|
|
@@ -160,28 +172,54 @@ export function ContextMenu({
|
|
|
160
172
|
</DropdownMenuItem>
|
|
161
173
|
</DropdownMenuGroup>
|
|
162
174
|
)}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
175
|
+
|
|
176
|
+
<DropdownMenuGroup>
|
|
177
|
+
<DropdownMenuSub>
|
|
178
|
+
<DropdownMenuSubTrigger subMenuTitle="Quality">
|
|
179
|
+
<View
|
|
180
|
+
style={[
|
|
181
|
+
zero.flex.values[1],
|
|
182
|
+
zero.layout.flex.row,
|
|
183
|
+
zero.layout.flex.spaceBetween,
|
|
184
|
+
zero.pr[4],
|
|
185
|
+
]}
|
|
186
|
+
>
|
|
187
|
+
<Text>Quality</Text>
|
|
188
|
+
<Text muted>
|
|
189
|
+
({quality}, {lowLatency ? "low latency" : "regular latency"}
|
|
190
|
+
)
|
|
191
|
+
</Text>
|
|
192
|
+
</View>
|
|
193
|
+
</DropdownMenuSubTrigger>
|
|
194
|
+
<DropdownMenuSubContent>
|
|
195
|
+
<DropdownMenuGroup title="Resolution">
|
|
196
|
+
<DropdownMenuRadioGroup
|
|
197
|
+
value={quality}
|
|
198
|
+
onValueChange={setQuality}
|
|
199
|
+
>
|
|
200
|
+
<DropdownMenuRadioItem value="source">
|
|
201
|
+
<Text>Source (Original Quality)</Text>
|
|
202
|
+
</DropdownMenuRadioItem>
|
|
203
|
+
{qualities.map((r) => (
|
|
204
|
+
<DropdownMenuRadioItem key={r.name} value={r.name}>
|
|
205
|
+
<Text>{r.name}</Text>
|
|
206
|
+
</DropdownMenuRadioItem>
|
|
207
|
+
))}
|
|
208
|
+
</DropdownMenuRadioGroup>
|
|
209
|
+
</DropdownMenuGroup>
|
|
210
|
+
<DropdownMenuGroup>
|
|
211
|
+
<DropdownMenuCheckboxItem
|
|
212
|
+
checked={lowLatency}
|
|
213
|
+
onCheckedChange={() => setLowLatency(!lowLatency)}
|
|
214
|
+
>
|
|
215
|
+
<Text>Low Latency</Text>
|
|
216
|
+
</DropdownMenuCheckboxItem>
|
|
217
|
+
</DropdownMenuGroup>
|
|
218
|
+
<DropdownMenuInfo description="Reduces the delay between video and chat for a more real-time experience." />
|
|
219
|
+
</DropdownMenuSubContent>
|
|
220
|
+
</DropdownMenuSub>
|
|
174
221
|
</DropdownMenuGroup>
|
|
175
222
|
<DropdownMenuGroup title="Advanced">
|
|
176
|
-
<DropdownMenuCheckboxItem
|
|
177
|
-
checked={lowLatency}
|
|
178
|
-
onCheckedChange={() => setLowLatency(!lowLatency)}
|
|
179
|
-
>
|
|
180
|
-
<Text>Low Latency</Text>
|
|
181
|
-
</DropdownMenuCheckboxItem>
|
|
182
|
-
</DropdownMenuGroup>
|
|
183
|
-
<DropdownMenuInfo description="Reduces the delay between video and chat for a more real-time experience." />
|
|
184
|
-
<DropdownMenuGroup>
|
|
185
223
|
<DropdownMenuCheckboxItem
|
|
186
224
|
checked={debugInfo}
|
|
187
225
|
onCheckedChange={() => setShowDebugInfo(!debugInfo)}
|
|
@@ -196,6 +234,23 @@ export function ContextMenu({
|
|
|
196
234
|
setReportSubject={setReportSubject}
|
|
197
235
|
/>
|
|
198
236
|
</DropdownMenuGroup>
|
|
237
|
+
<View style={[pt[3], px[2], gap.all[2]]}>
|
|
238
|
+
{contentWarnings && contentWarnings.length > 0 && (
|
|
239
|
+
<View style={[gap.all[1]]}>
|
|
240
|
+
<Text size="base" color="muted">
|
|
241
|
+
Stream may contain
|
|
242
|
+
</Text>
|
|
243
|
+
<ContentWarnings warnings={contentWarnings} compact={true} />
|
|
244
|
+
</View>
|
|
245
|
+
)}
|
|
246
|
+
{contentRights && Object.keys(contentRights).length > 0 && (
|
|
247
|
+
<ContentRights
|
|
248
|
+
contentRights={contentRights}
|
|
249
|
+
size="xs"
|
|
250
|
+
color="muted"
|
|
251
|
+
/>
|
|
252
|
+
)}
|
|
253
|
+
</View>
|
|
199
254
|
</DropdownMenuContent>
|
|
200
255
|
</Portal>
|
|
201
256
|
</DropdownMenu>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Check } from "lucide-react-native";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { StyleSheet, TouchableOpacity, View } from "react-native";
|
|
4
|
-
import { useTheme } from "../../lib/theme/theme";
|
|
4
|
+
import { Theme, useTheme } from "../../lib/theme/theme";
|
|
5
5
|
import { Text } from "./text";
|
|
6
6
|
|
|
7
7
|
export interface CheckboxProps {
|
|
@@ -60,9 +60,23 @@ export const Checkbox = forwardRef<any, CheckboxProps>(
|
|
|
60
60
|
</View>
|
|
61
61
|
{(label || description) && (
|
|
62
62
|
<View style={styles.content}>
|
|
63
|
-
{label &&
|
|
63
|
+
{label && (
|
|
64
|
+
<Text
|
|
65
|
+
size={size === "sm" ? "sm" : size === "lg" ? "lg" : "base"}
|
|
66
|
+
color={disabled ? "muted" : "default"}
|
|
67
|
+
leading="snug"
|
|
68
|
+
>
|
|
69
|
+
{label}
|
|
70
|
+
</Text>
|
|
71
|
+
)}
|
|
64
72
|
{description && (
|
|
65
|
-
<Text
|
|
73
|
+
<Text
|
|
74
|
+
size={size === "sm" ? "xs" : size === "lg" ? "base" : "sm"}
|
|
75
|
+
color={disabled ? "muted" : "muted"}
|
|
76
|
+
style={{ marginTop: theme.spacing[1] }}
|
|
77
|
+
>
|
|
78
|
+
{description}
|
|
79
|
+
</Text>
|
|
66
80
|
)}
|
|
67
81
|
</View>
|
|
68
82
|
)}
|
|
@@ -74,7 +88,7 @@ export const Checkbox = forwardRef<any, CheckboxProps>(
|
|
|
74
88
|
Checkbox.displayName = "Checkbox";
|
|
75
89
|
|
|
76
90
|
function createStyles(
|
|
77
|
-
theme:
|
|
91
|
+
theme: Theme,
|
|
78
92
|
size: string,
|
|
79
93
|
disabled: boolean,
|
|
80
94
|
checked: boolean,
|
|
@@ -90,13 +104,13 @@ function createStyles(
|
|
|
90
104
|
checkboxSize: 20,
|
|
91
105
|
borderRadius: 4,
|
|
92
106
|
padding: theme.spacing[1],
|
|
93
|
-
gap: theme.spacing[
|
|
107
|
+
gap: theme.spacing[1],
|
|
94
108
|
},
|
|
95
109
|
lg: {
|
|
96
110
|
checkboxSize: 24,
|
|
97
111
|
borderRadius: 6,
|
|
98
|
-
padding: theme.spacing[
|
|
99
|
-
gap: theme.spacing[
|
|
112
|
+
padding: theme.spacing[1],
|
|
113
|
+
gap: theme.spacing[2],
|
|
100
114
|
},
|
|
101
115
|
};
|
|
102
116
|
|
|
@@ -116,7 +130,7 @@ function createStyles(
|
|
|
116
130
|
? theme.colors.border
|
|
117
131
|
: checked
|
|
118
132
|
? theme.colors.primary
|
|
119
|
-
: theme.colors.
|
|
133
|
+
: theme.colors.textMuted,
|
|
120
134
|
borderRadius: currentSize.borderRadius,
|
|
121
135
|
backgroundColor: disabled
|
|
122
136
|
? theme.colors.muted
|
|
@@ -128,20 +142,8 @@ function createStyles(
|
|
|
128
142
|
},
|
|
129
143
|
content: {
|
|
130
144
|
flex: 1,
|
|
131
|
-
paddingTop: currentSize.padding * 0.
|
|
145
|
+
paddingTop: currentSize.padding * 0.25,
|
|
132
146
|
paddingLeft: theme.spacing[2],
|
|
133
147
|
},
|
|
134
|
-
label: {
|
|
135
|
-
fontSize: size === "sm" ? 14 : size === "lg" ? 18 : 16,
|
|
136
|
-
fontWeight: "500",
|
|
137
|
-
color: disabled ? theme.colors.textDisabled : theme.colors.text,
|
|
138
|
-
lineHeight: size === "sm" ? 18 : size === "lg" ? 22 : 20,
|
|
139
|
-
},
|
|
140
|
-
description: {
|
|
141
|
-
fontSize: size === "sm" ? 12 : size === "lg" ? 16 : 14,
|
|
142
|
-
color: disabled ? theme.colors.textDisabled : theme.colors.textMuted,
|
|
143
|
-
marginTop: theme.spacing[1],
|
|
144
|
-
lineHeight: size === "sm" ? 16 : size === "lg" ? 20 : 18,
|
|
145
|
-
},
|
|
146
148
|
});
|
|
147
149
|
}
|