An ATproto social media client -- with an independent Appview.

refactor: we aren't deer

thank you aviva for the work you've done :)

serenity c6532ccc b25fbacc

+27 -25
+4 -4
src/Navigation.tsx
··· 95 import {ActivityPrivacySettingsScreen} from '#/screens/Settings/ActivityPrivacySettings' 96 import {AppearanceSettingsScreen} from '#/screens/Settings/AppearanceSettings' 97 import {AppIconSettingsScreen} from '#/screens/Settings/AppIconSettings' 98 import {InterestsSettingsScreen} from '#/screens/Settings/InterestsSettings' 99 import {LegacyNotificationSettingsScreen} from '#/screens/Settings/LegacyNotificationSettings' 100 import {NotificationSettingsScreen} from '#/screens/Settings/NotificationSettings' ··· 129 import {AccountSettingsScreen} from './screens/Settings/AccountSettings' 130 import {AppPasswordsScreen} from './screens/Settings/AppPasswords' 131 import {ContentAndMediaSettingsScreen} from './screens/Settings/ContentAndMediaSettings' 132 - import {DeerSettingsScreen} from './screens/Settings/DeerSettings' 133 import {ExternalMediaPreferencesScreen} from './screens/Settings/ExternalMediaPreferences' 134 import {FollowingFeedPreferencesScreen} from './screens/Settings/FollowingFeedPreferences' 135 import {LanguageSettingsScreen} from './screens/Settings/LanguageSettings' ··· 386 }} 387 /> 388 <Stack.Screen 389 - name="CatskySettings" 390 - getComponent={() => DeerSettingsScreen} 391 options={{ 392 - title: title(msg`Deer Settings`), 393 requireAuth: true, 394 }} 395 />
··· 95 import {ActivityPrivacySettingsScreen} from '#/screens/Settings/ActivityPrivacySettings' 96 import {AppearanceSettingsScreen} from '#/screens/Settings/AppearanceSettings' 97 import {AppIconSettingsScreen} from '#/screens/Settings/AppIconSettings' 98 + import {ExperimentalSettingsScreen} from '#/screens/Settings/ExperimentalSettings' 99 import {InterestsSettingsScreen} from '#/screens/Settings/InterestsSettings' 100 import {LegacyNotificationSettingsScreen} from '#/screens/Settings/LegacyNotificationSettings' 101 import {NotificationSettingsScreen} from '#/screens/Settings/NotificationSettings' ··· 130 import {AccountSettingsScreen} from './screens/Settings/AccountSettings' 131 import {AppPasswordsScreen} from './screens/Settings/AppPasswords' 132 import {ContentAndMediaSettingsScreen} from './screens/Settings/ContentAndMediaSettings' 133 import {ExternalMediaPreferencesScreen} from './screens/Settings/ExternalMediaPreferences' 134 import {FollowingFeedPreferencesScreen} from './screens/Settings/FollowingFeedPreferences' 135 import {LanguageSettingsScreen} from './screens/Settings/LanguageSettings' ··· 386 }} 387 /> 388 <Stack.Screen 389 + name="ExperimentalSettings" 390 + getComponent={() => ExperimentalSettingsScreen} 391 options={{ 392 + title: title(msg`Experimental Settings`), 393 requireAuth: true, 394 }} 395 />
+1 -1
src/lib/routes/types.ts
··· 123 Feeds: undefined 124 Notifications: undefined 125 Messages: {pushToConversation?: string; animation?: 'push' | 'pop'} 126 - CatskySettings: undefined 127 } 128 129 export type AllNavigatorParams = CommonNavigatorParams & {
··· 123 Feeds: undefined 124 Notifications: undefined 125 Messages: {pushToConversation?: string; animation?: 'push' | 'pop'} 126 + ExperimentalSettings: undefined 127 } 128 129 export type AllNavigatorParams = CommonNavigatorParams & {
+6 -6
src/lib/statsig/statsig.tsx
··· 138 return cache 139 } 140 141 - function writeDeerGateCache(cache: Map<string, boolean>) { 142 - device.set(['deerGateCache'], JSON.stringify(Object.fromEntries(cache))) 143 } 144 145 - export function resetDeerGateCache() { 146 - writeDeerGateCache(new Map()) 147 } 148 149 export function useGate(): (gateName: Gate, options?: GateOptions) => boolean { ··· 166 } 167 } 168 cache.set(gateName, value) 169 - writeDeerGateCache(cache) 170 return value 171 }, 172 [cache], ··· 190 const dangerousSetGate = React.useCallback( 191 (gateName: Gate, value: boolean) => { 192 cache.set(gateName, value) 193 - writeDeerGateCache(cache) 194 }, 195 [cache], 196 )
··· 138 return cache 139 } 140 141 + function writeCatskyGateCache(cache: Map<string, boolean>) { 142 + device.set(['catskyGateCache'], JSON.stringify(Object.fromEntries(cache))) 143 } 144 145 + export function resetCatskyGateCache() { 146 + writeCatskyGateCache(new Map()) 147 } 148 149 export function useGate(): (gateName: Gate, options?: GateOptions) => boolean { ··· 166 } 167 } 168 cache.set(gateName, value) 169 + writeCatskyGateCache(cache) 170 return value 171 }, 172 [cache], ··· 190 const dangerousSetGate = React.useCallback( 191 (gateName: Gate, value: boolean) => { 192 cache.set(gateName, value) 193 + writeCatskyGateCache(cache) 194 }, 195 [cache], 196 )
+1 -1
src/routes.ts
··· 47 PreferencesThreads: '/settings/threads', 48 PreferencesExternalEmbeds: '/settings/external-embeds', 49 AccessibilitySettings: '/settings/accessibility', 50 - DeerSettings: '/settings/deer', 51 AppearanceSettings: '/settings/appearance', 52 SavedFeeds: '/settings/saved-feeds', 53 AccountSettings: '/settings/account',
··· 47 PreferencesThreads: '/settings/threads', 48 PreferencesExternalEmbeds: '/settings/external-embeds', 49 AccessibilitySettings: '/settings/accessibility', 50 + ExperimentalSettings: '/settings/experimental', 51 AppearanceSettings: '/settings/appearance', 52 SavedFeeds: '/settings/saved-feeds', 53 AccountSettings: '/settings/account',
+6 -6
src/screens/Settings/DeerSettings.tsx src/screens/Settings/ExperimentalSettings.tsx
··· 6 import {type CommonNavigatorParams} from '#/lib/routes/types' 7 import {type Gate} from '#/lib/statsig/gates' 8 import { 9 - resetDeerGateCache, 10 useDangerousSetGate, 11 useGatesCache, 12 } from '#/lib/statsig/statsig' ··· 23 import {atoms as a} from '#/alf' 24 import {Admonition} from '#/components/Admonition' 25 import * as Toggle from '#/components/forms/Toggle' 26 - import {Atom_Stroke2_Corner0_Rounded as DeerIcon} from '#/components/icons/Atom' 27 import {Eye_Stroke2_Corner0_Rounded as VisibilityIcon} from '#/components/icons/Eye' 28 import {PaintRoller_Stroke2_Corner2_Rounded as PaintRollerIcon} from '#/components/icons/PaintRoller' 29 import * as Layout from '#/components/Layout' 30 31 type Props = NativeStackScreenProps<CommonNavigatorParams> 32 33 - export function DeerSettingsScreen({}: Props) { 34 const {_} = useLingui() 35 36 const goLinksEnabled = useGoLinksEnabled() ··· 58 <Layout.Header.BackButton /> 59 <Layout.Header.Content> 60 <Layout.Header.TitleText> 61 - <Trans>Deer</Trans> 62 </Layout.Header.TitleText> 63 </Layout.Header.Content> 64 <Layout.Header.Slot /> ··· 66 <Layout.Content> 67 <SettingsList.Container> 68 <SettingsList.Group contentContainerStyle={[a.gap_sm]}> 69 - <SettingsList.ItemIcon icon={DeerIcon} /> 70 <SettingsList.ItemText> 71 <Trans>Redirects</Trans> 72 </SettingsList.ItemText> ··· 160 <SettingsList.BadgeButton 161 label={_(msg`Reset gates`)} 162 onPress={() => { 163 - resetDeerGateCache() 164 setGatesView({}) 165 }} 166 />
··· 6 import {type CommonNavigatorParams} from '#/lib/routes/types' 7 import {type Gate} from '#/lib/statsig/gates' 8 import { 9 + resetCatskyGateCache, 10 useDangerousSetGate, 11 useGatesCache, 12 } from '#/lib/statsig/statsig' ··· 23 import {atoms as a} from '#/alf' 24 import {Admonition} from '#/components/Admonition' 25 import * as Toggle from '#/components/forms/Toggle' 26 + import {Atom_Stroke2_Corner0_Rounded as ExperimentalIcon} from '#/components/icons/Atom' 27 import {Eye_Stroke2_Corner0_Rounded as VisibilityIcon} from '#/components/icons/Eye' 28 import {PaintRoller_Stroke2_Corner2_Rounded as PaintRollerIcon} from '#/components/icons/PaintRoller' 29 import * as Layout from '#/components/Layout' 30 31 type Props = NativeStackScreenProps<CommonNavigatorParams> 32 33 + export function ExperimentalSettingsScreen({}: Props) { 34 const {_} = useLingui() 35 36 const goLinksEnabled = useGoLinksEnabled() ··· 58 <Layout.Header.BackButton /> 59 <Layout.Header.Content> 60 <Layout.Header.TitleText> 61 + <Trans>Experimental</Trans> 62 </Layout.Header.TitleText> 63 </Layout.Header.Content> 64 <Layout.Header.Slot /> ··· 66 <Layout.Content> 67 <SettingsList.Container> 68 <SettingsList.Group contentContainerStyle={[a.gap_sm]}> 69 + <SettingsList.ItemIcon icon={ExperimentalIcon} /> 70 <SettingsList.ItemText> 71 <Trans>Redirects</Trans> 72 </SettingsList.ItemText> ··· 160 <SettingsList.BadgeButton 161 label={_(msg`Reset gates`)} 162 onPress={() => { 163 + resetCatskyGateCache() 164 setGatesView({}) 165 }} 166 />
+6 -4
src/screens/Settings/Settings.tsx
··· 40 import {useDialogControl} from '#/components/Dialog' 41 import {SwitchAccountDialog} from '#/components/dialogs/SwitchAccount' 42 import {Accessibility_Stroke2_Corner2_Rounded as AccessibilityIcon} from '#/components/icons/Accessibility' 43 - import {Atom_Stroke2_Corner0_Rounded as DeerIcon} from '#/components/icons/Atom' 44 import {Bell_Stroke2_Corner0_Rounded as NotificationIcon} from '#/components/icons/Bell' 45 import {BubbleInfo_Stroke2_Corner2_Rounded as BubbleInfoIcon} from '#/components/icons/BubbleInfo' 46 import {ChevronTop_Stroke2_Corner0_Rounded as ChevronUpIcon} from '#/components/icons/Chevron' ··· 216 <Trans>Appearance</Trans> 217 </SettingsList.ItemText> 218 </SettingsList.LinkItem> 219 - <SettingsList.LinkItem to="/settings/deer" label={_(msg`Deer`)}> 220 - <SettingsList.ItemIcon icon={DeerIcon} /> 221 <SettingsList.ItemText> 222 - <Trans>Deer</Trans> 223 </SettingsList.ItemText> 224 </SettingsList.LinkItem> 225 <SettingsList.LinkItem
··· 40 import {useDialogControl} from '#/components/Dialog' 41 import {SwitchAccountDialog} from '#/components/dialogs/SwitchAccount' 42 import {Accessibility_Stroke2_Corner2_Rounded as AccessibilityIcon} from '#/components/icons/Accessibility' 43 + import {Atom_Stroke2_Corner0_Rounded as ExperimentalIcon} from '#/components/icons/Atom' 44 import {Bell_Stroke2_Corner0_Rounded as NotificationIcon} from '#/components/icons/Bell' 45 import {BubbleInfo_Stroke2_Corner2_Rounded as BubbleInfoIcon} from '#/components/icons/BubbleInfo' 46 import {ChevronTop_Stroke2_Corner0_Rounded as ChevronUpIcon} from '#/components/icons/Chevron' ··· 216 <Trans>Appearance</Trans> 217 </SettingsList.ItemText> 218 </SettingsList.LinkItem> 219 + <SettingsList.LinkItem 220 + to="/settings/experimental" 221 + label={_(msg`Experimental`)}> 222 + <SettingsList.ItemIcon icon={ExperimentalIcon} /> 223 <SettingsList.ItemText> 224 + <Trans>Experimental</Trans> 225 </SettingsList.ItemText> 226 </SettingsList.LinkItem> 227 <SettingsList.LinkItem
+1 -1
src/state/persisted/schema.ts
··· 124 hasCheckedForStarterPack: z.boolean().optional(), 125 subtitlesEnabled: z.boolean().optional(), 126 127 - // deer 128 goLinksEnabled: z.boolean().optional(), 129 constellationEnabled: z.boolean().optional(), 130 directFetchRecords: z.boolean().optional(),
··· 124 hasCheckedForStarterPack: z.boolean().optional(), 125 subtitlesEnabled: z.boolean().optional(), 126 127 + // experimental (deer/zeppelin/fork niche toggle stuff) 128 goLinksEnabled: z.boolean().optional(), 129 constellationEnabled: z.boolean().optional(), 130 directFetchRecords: z.boolean().optional(),
+2 -2
src/storage/schema.ts
··· 44 policyUpdateDebugOverride?: boolean 45 [PolicyUpdate202508]?: boolean 46 47 - // deer 48 - deerGateCache: string 49 } 50 51 export type Account = {
··· 44 policyUpdateDebugOverride?: boolean 45 [PolicyUpdate202508]?: boolean 46 47 + // catsky 48 + catskyGateCache: string 49 } 50 51 export type Account = {