forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {Platform} from 'react-native'
2import {setStringAsync} from 'expo-clipboard'
3import * as FileSystem from 'expo-file-system/legacy'
4import {Image} from 'expo-image'
5import {msg, Trans} from '@lingui/macro'
6import {useLingui} from '@lingui/react'
7import {type NativeStackScreenProps} from '@react-navigation/native-stack'
8import {useMutation} from '@tanstack/react-query'
9
10import {STATUS_PAGE_URL} from '#/lib/constants'
11import {type CommonNavigatorParams} from '#/lib/routes/types'
12import * as Toast from '#/view/com/util/Toast'
13import * as SettingsList from '#/screens/Settings/components/SettingsList'
14import {Atom_Stroke2_Corner0_Rounded as AtomIcon} from '#/components/icons/Atom'
15import {BroomSparkle_Stroke2_Corner2_Rounded as BroomSparkleIcon} from '#/components/icons/BroomSparkle'
16import {CodeLines_Stroke2_Corner2_Rounded as CodeLinesIcon} from '#/components/icons/CodeLines'
17import {Globe_Stroke2_Corner0_Rounded as GlobeIcon} from '#/components/icons/Globe'
18import {Newspaper_Stroke2_Corner2_Rounded as NewspaperIcon} from '#/components/icons/Newspaper'
19import {Wrench_Stroke2_Corner2_Rounded as WrenchIcon} from '#/components/icons/Wrench'
20import * as Layout from '#/components/Layout'
21import {Loader} from '#/components/Loader'
22import {getDeviceId} from '#/analytics/identifiers'
23import {IS_ANDROID, IS_IOS, IS_NATIVE} from '#/env'
24import * as env from '#/env'
25import {useDemoMode} from '#/storage/hooks/demo-mode'
26import {useDevMode} from '#/storage/hooks/dev-mode'
27import {OTAInfo} from './components/OTAInfo'
28
29type Props = NativeStackScreenProps<CommonNavigatorParams, 'AboutSettings'>
30export function AboutSettingsScreen({}: Props) {
31 const {_, i18n} = useLingui()
32 const [devModeEnabled, setDevModeEnabled] = useDevMode()
33 const [demoModeEnabled, setDemoModeEnabled] = useDemoMode()
34
35 const {mutate: onClearImageCache, isPending: isClearingImageCache} =
36 useMutation({
37 mutationFn: async () => {
38 const freeSpaceBefore = await FileSystem.getFreeDiskStorageAsync()
39 await Image.clearDiskCache()
40 const freeSpaceAfter = await FileSystem.getFreeDiskStorageAsync()
41 const spaceDiff = freeSpaceBefore - freeSpaceAfter
42 return spaceDiff * -1
43 },
44 onSuccess: sizeDiffBytes => {
45 if (IS_ANDROID) {
46 Toast.show(
47 _(
48 msg({
49 message: `Image cache cleared, freed ${i18n.number(
50 Math.abs(sizeDiffBytes / 1024 / 1024),
51 {
52 notation: 'compact',
53 style: 'unit',
54 unit: 'megabyte',
55 },
56 )}`,
57 comment: `Android-only toast message which includes amount of space freed using localized number formatting`,
58 }),
59 ),
60 )
61 } else {
62 Toast.show(_(msg`Image cache cleared`))
63 }
64 },
65 })
66
67 return (
68 <Layout.Screen>
69 <Layout.Header.Outer>
70 <Layout.Header.BackButton />
71 <Layout.Header.Content>
72 <Layout.Header.TitleText>
73 <Trans>About</Trans>
74 </Layout.Header.TitleText>
75 </Layout.Header.Content>
76 <Layout.Header.Slot />
77 </Layout.Header.Outer>
78 <Layout.Content>
79 <SettingsList.Container>
80 <SettingsList.LinkItem
81 to="https://witchsky.app/about/tos"
82 label={_(msg`Terms of Service`)}>
83 <SettingsList.ItemIcon icon={NewspaperIcon} />
84 <SettingsList.ItemText>
85 <Trans>Terms of Service</Trans>
86 </SettingsList.ItemText>
87 </SettingsList.LinkItem>
88 <SettingsList.LinkItem
89 to="https://witchsky.app/about/privacy"
90 label={_(msg`Privacy Policy`)}>
91 <SettingsList.ItemIcon icon={NewspaperIcon} />
92 <SettingsList.ItemText>
93 <Trans>Privacy Policy</Trans>
94 </SettingsList.ItemText>
95 </SettingsList.LinkItem>
96 <SettingsList.LinkItem
97 to={STATUS_PAGE_URL}
98 label={_(msg`Status Page`)}>
99 <SettingsList.ItemIcon icon={GlobeIcon} />
100 <SettingsList.ItemText>
101 <Trans>Status Page</Trans>
102 </SettingsList.ItemText>
103 </SettingsList.LinkItem>
104 <SettingsList.Divider />
105 <SettingsList.LinkItem to="/sys/log" label={_(msg`System log`)}>
106 <SettingsList.ItemIcon icon={CodeLinesIcon} />
107 <SettingsList.ItemText>
108 <Trans>System log</Trans>
109 </SettingsList.ItemText>
110 </SettingsList.LinkItem>
111 {IS_NATIVE && (
112 <SettingsList.PressableItem
113 onPress={() => onClearImageCache()}
114 label={_(msg`Clear image cache`)}
115 disabled={isClearingImageCache}>
116 <SettingsList.ItemIcon icon={BroomSparkleIcon} />
117 <SettingsList.ItemText>
118 <Trans>Clear image cache</Trans>
119 </SettingsList.ItemText>
120 {isClearingImageCache && <SettingsList.ItemIcon icon={Loader} />}
121 </SettingsList.PressableItem>
122 )}
123 <SettingsList.PressableItem
124 label={_(msg`Version ${env.APP_VERSION}`)}
125 accessibilityHint={_(msg`Copies build version to clipboard`)}
126 onLongPress={() => {
127 const newDevModeEnabled = !devModeEnabled
128 setDevModeEnabled(newDevModeEnabled)
129 Toast.show(
130 newDevModeEnabled
131 ? _(
132 msg({
133 message: 'Developer mode enabled',
134 context: 'toast',
135 }),
136 )
137 : _(
138 msg({
139 message: 'Developer mode disabled',
140 context: 'toast',
141 }),
142 ),
143 )
144 }}
145 onPress={() => {
146 setStringAsync(
147 `Build version: ${env.APP_VERSION}; Bundle info: ${env.APP_METADATA}; Bundle date: ${env.BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}; Device ID: ${getDeviceId() ?? 'N/A'}`,
148 )
149 Toast.show(_(msg`Copied build version to clipboard`))
150 }}>
151 <SettingsList.ItemIcon icon={WrenchIcon} />
152 <SettingsList.ItemText>
153 <Trans>Version {env.APP_VERSION}</Trans>
154 </SettingsList.ItemText>
155 <SettingsList.BadgeText>{env.APP_METADATA}</SettingsList.BadgeText>
156 </SettingsList.PressableItem>
157 {devModeEnabled && (
158 <>
159 <OTAInfo />
160 {IS_IOS && (
161 <SettingsList.PressableItem
162 onPress={() => {
163 const newDemoModeEnabled = !demoModeEnabled
164 setDemoModeEnabled(newDemoModeEnabled)
165 Toast.show(
166 'Demo mode ' +
167 (newDemoModeEnabled ? 'enabled' : 'disabled'),
168 )
169 }}
170 label={
171 demoModeEnabled ? 'Disable demo mode' : 'Enable demo mode'
172 }
173 disabled={isClearingImageCache}>
174 <SettingsList.ItemIcon icon={AtomIcon} />
175 <SettingsList.ItemText>
176 {demoModeEnabled ? 'Disable demo mode' : 'Enable demo mode'}
177 </SettingsList.ItemText>
178 </SettingsList.PressableItem>
179 )}
180 </>
181 )}
182 </SettingsList.Container>
183 </Layout.Content>
184 </Layout.Screen>
185 )
186}