Skip to content
70 linesCodeBlameRaw
1import Constants from "expo-constants";
2import { Stack } from "expo-router";
3import * as WebBrowser from "expo-web-browser";
4import { Check, ExternalLink, LogOut } from "lucide-react-native";
5import { View } from "react-native";
6
7import { Avatar, Button, Row, Screen, SectionHeader, Text } from "@/components/ui";
8import { isHosted, siteUrl } from "@/lib/server";
9import { useSignedIn } from "@/lib/session";
10import { space, useColors } from "@/theme";
11
12/** You: who is signed in, the workspace the app shows, and signing out. */
13export default function You() {
14 const { me, workspace, server, client, selectWorkspace, signOut } = useSignedIn();
15 const colors = useColors();
16 const name = me.display_username ?? me.username;
17 const oauth = client.credentials.kind === "oauth";
18
19 return (
20 <Screen scroll style={{ paddingHorizontal: 0 }}>
21 <Stack.Screen options={{ title: "You" }} />
22 <View style={{ flexDirection: "row", gap: space.md, alignItems: "center", paddingHorizontal: space.lg }}>
23 <Avatar name={name} uri={me.avatar ? `${server.site}/avatars/${me.avatar}` : null} size={48} />
24 <View style={{ flex: 1 }}>
25 <Text size="heading">{name}</Text>
26 <Text size="small" tone="muted">
27 {isHosted(server) ? "g1t.sh" : new URL(server.site).host}
28 </Text>
29 </View>
30 </View>
31
32 <View>
33 <SectionHeader title="Workspaces" />
34 {(me.workspaces ?? []).map((one) => (
35 <Row
36 key={one.slug}
37 leading={<Avatar name={one.name ?? one.slug} uri={one.avatar ? `${server.site}/avatars/${one.avatar}` : null} />}
38 title={one.name ?? one.slug}
39 subtitle={`${one.slug} · ${one.role}`}
40 trailing={one.slug === workspace?.slug ? <Check size={18} color={colors.accent} /> : null}
41 chevron={false}
42 onPress={() => selectWorkspace(one.slug)}
43 />
44 ))}
45 </View>
46
47 <View>
48 <SectionHeader title="Signed in" />
49 <Row
50 title={oauth ? "With g1t" : "With an access token"}
51 subtitle={
52 oauth
53 ? "End or narrow the app's access in Settings → Connected applications."
54 : "The token you pasted. Delete it in Settings → Access tokens to end it."
55 }
56 trailing={<ExternalLink size={16} color={colors.faint} />}
57 chevron={false}
58 onPress={() => WebBrowser.openBrowserAsync(siteUrl(server, oauth ? "/settings/applications" : "/settings/tokens"))}
59 />
60 </View>
61
62 <View style={{ paddingHorizontal: space.lg, gap: space.md }}>
63 <Button title="Sign out" variant="danger" icon={LogOut} onPress={signOut} />
64 <Text size="small" tone="faint" style={{ textAlign: "center" }}>
65 g1t {Constants.expoConfig?.version ?? ""}
66 </Text>
67 </View>
68 </Screen>
69 );
70}