tangled
alpha
login
or
join now
teal.fm
/
teal
110
fork
atom
Your music, beautifully tracked. All yours. (coming soon)
teal.fm
teal-fm
atproto
110
fork
atom
overview
issues
pulls
pipelines
add more info + did changer in settings
Natalie B
10 months ago
ab00c4c8
18a0d2f9
+163
1 changed file
expand all
collapse all
unified
split
apps
amethyst
app
(tabs)
settings
index.tsx
+163
apps/amethyst/app/(tabs)/settings/index.tsx
···
1
1
+
import React, { useState } from "react";
2
2
+
import { Text } from "@/components/ui/text";
3
3
+
import { ScrollView, Switch, View } from "react-native";
4
4
+
import { Link, Stack } from "expo-router";
5
5
+
import { useColorScheme } from "@/lib/useColorScheme";
6
6
+
import { cn } from "@/lib/utils";
7
7
+
import { Button } from "@/components/ui/button";
8
8
+
9
9
+
import pkg from "@/package.json";
10
10
+
import { useStore } from "@/stores/mainStore";
11
11
+
import { Input } from "@/components/ui/input";
12
12
+
13
13
+
export default function Settings() {
14
14
+
const { colorScheme, setColorScheme } = useColorScheme();
15
15
+
const appviewDid = useStore((state) => state.tealDid);
16
16
+
const setAppviewDid = useStore((state) => state.setTealDid);
17
17
+
18
18
+
const colorSchemeOptions = [
19
19
+
{ label: "Light", value: "light" },
20
20
+
{ label: "Dark", value: "dark" },
21
21
+
{ label: "System", value: "system" },
22
22
+
];
23
23
+
24
24
+
return (
25
25
+
<ScrollView className="flex-1 justify-start items-center gap-5 bg-background w-full">
26
26
+
<Stack.Screen
27
27
+
options={{
28
28
+
title: "Settings",
29
29
+
headerBackButtonDisplayMode: "minimal",
30
30
+
headerShown: true,
31
31
+
}}
32
32
+
/>
33
33
+
<View className="max-w-2xl flex-1 w-screen flex flex-col p-4 divide-y divide-muted-foreground/50 gap-4 rounded-xl my-2 mx-5">
34
34
+
<ButtonSelector
35
35
+
text="Theme"
36
36
+
values={colorSchemeOptions}
37
37
+
selectedValue={colorScheme}
38
38
+
setSelectedValue={setColorScheme}
39
39
+
/>
40
40
+
<TextInputRow
41
41
+
labelText="Appview DID"
42
42
+
initialValue={appviewDid || ""} // Ensure currentValue is a string
43
43
+
onSubmit={(e) => setAppviewDid(e)}
44
44
+
placeholder="Enter your Appview DID (e.g., did:plc:...)"
45
45
+
/>
46
46
+
<Link href="/auth/logoutModal" asChild>
47
47
+
<Button variant="destructive" size="sm" className="w-max pb-1">
48
48
+
<Text>Sign out</Text>
49
49
+
</Button>
50
50
+
</Link>
51
51
+
<View>
52
52
+
<Text className="text-muted-foreground">
53
53
+
teal.fm amethyst ver. {pkg.version}
54
54
+
</Text>
55
55
+
<Text className="text-muted-foreground">
56
56
+
react native{" "}
57
57
+
{pkg.dependencies["react-native"]
58
58
+
.replace("~", "")
59
59
+
.split(".")
60
60
+
.slice(0, 2)
61
61
+
.join(".")}
62
62
+
, expo {pkg.dependencies.expo.split(".")[0].replace("~", "")}.
63
63
+
</Text>
64
64
+
</View>
65
65
+
</View>
66
66
+
</ScrollView>
67
67
+
);
68
68
+
}
69
69
+
70
70
+
function ToggleSwitch({
71
71
+
text,
72
72
+
isEnabled,
73
73
+
setIsEnabled,
74
74
+
}: {
75
75
+
text: string;
76
76
+
isEnabled: boolean;
77
77
+
setIsEnabled: React.Dispatch<React.SetStateAction<boolean>>;
78
78
+
}) {
79
79
+
const toggleSwitch = () =>
80
80
+
setIsEnabled((previousState: boolean) => !previousState);
81
81
+
82
82
+
return (
83
83
+
<View className="flex-row items-center justify-between">
84
84
+
<Text className="text-lg">{text}</Text>
85
85
+
<Switch className="ml-4" value={isEnabled} onValueChange={toggleSwitch} />
86
86
+
</View>
87
87
+
);
88
88
+
}
89
89
+
90
90
+
/// A selector component for smaller selections (usu. <3 values)
91
91
+
function ButtonSelector({
92
92
+
text,
93
93
+
values,
94
94
+
selectedValue,
95
95
+
setSelectedValue,
96
96
+
}: {
97
97
+
text: string;
98
98
+
values: { label: string; value: string }[];
99
99
+
selectedValue: string;
100
100
+
setSelectedValue: (value: any) => void;
101
101
+
}) {
102
102
+
return (
103
103
+
<View className="items-start gap-2 pt-2">
104
104
+
<Text className="text-base font-semibold">{text}</Text>
105
105
+
<View className="flex-row items-center justify-around gap-1 w-full bg-muted h-10 px-1 rounded-xl">
106
106
+
{values.map(({ label, value }) => (
107
107
+
<Button
108
108
+
key={value}
109
109
+
onPress={() => setSelectedValue(value)}
110
110
+
className={`flex-1 w-full h-8`}
111
111
+
variant={selectedValue === value ? "secondary" : "ghost"}
112
112
+
>
113
113
+
<Text
114
114
+
className={cn(
115
115
+
selectedValue === value
116
116
+
? "text-foreground"
117
117
+
: "text-muted-foreground",
118
118
+
)}
119
119
+
>
120
120
+
{label}
121
121
+
</Text>
122
122
+
</Button>
123
123
+
))}
124
124
+
</View>
125
125
+
</View>
126
126
+
);
127
127
+
}
128
128
+
129
129
+
function TextInputRow({
130
130
+
labelText,
131
131
+
initialValue = "", // Added initialValue prop, defaults to empty string
132
132
+
onSubmit,
133
133
+
placeholder,
134
134
+
}: {
135
135
+
labelText: string;
136
136
+
initialValue?: string; // Made initialValue optional
137
137
+
onSubmit: (value: string) => void; // onSubmit now takes the string value
138
138
+
placeholder?: string;
139
139
+
}) {
140
140
+
const [inputValue, setInputValue] = useState(initialValue); // Internal state for the input
141
141
+
142
142
+
const handleSubmit = () => {
143
143
+
onSubmit(inputValue);
144
144
+
};
145
145
+
146
146
+
return (
147
147
+
<View className="items-start gap-2 pt-2">
148
148
+
<Text className="text-base font-semibold">{labelText}</Text>
149
149
+
<View className="flex-row gap-2 w-full items-center">
150
150
+
<Input
151
151
+
className="border border-muted-foreground/50 bg-transparent text-foreground h-10 w-full rounded-md px-3 py-2 text-base"
152
152
+
value={inputValue}
153
153
+
onChangeText={setInputValue} // Update internal state on change
154
154
+
placeholder={placeholder}
155
155
+
placeholderTextColor="hsl(var(--muted-foreground))"
156
156
+
/>
157
157
+
<Button onPress={handleSubmit} size="sm">
158
158
+
<Text>Submit</Text>
159
159
+
</Button>
160
160
+
</View>
161
161
+
</View>
162
162
+
);
163
163
+
}