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