···5import {RootSiblingParent} from 'react-native-root-siblings'
6import * as SplashScreen from 'expo-splash-screen'
7import {GestureHandlerRootView} from 'react-native-gesture-handler'
8-import {QueryClientProvider} from '@tanstack/react-query'
9import {
10 SafeAreaProvider,
11 initialWindowMetrics,
···22import {Shell} from 'view/shell'
23import * as notifications from 'lib/notifications/notifications'
24import * as Toast from 'view/com/util/Toast'
25-import {queryClient} from 'lib/react-query'
000026import {TestCtrls} from 'view/com/testing/TestCtrls'
27import {Provider as ShellStateProvider} from 'state/shell'
28import {Provider as ModalStateProvider} from 'state/modals'
···33import {Provider as PrefsStateProvider} from 'state/preferences'
34import {Provider as LoggedOutViewProvider} from 'state/shell/logged-out'
35import {Provider as SelectedFeedProvider} from 'state/shell/selected-feed'
036import I18nProvider from './locale/i18nProvider'
37import {
38 Provider as SessionProvider,
···79 // Resets the entire tree below when it changes:
80 key={currentAccount?.did}>
81 <StatsigProvider>
82- <LoggedOutViewProvider>
83- <SelectedFeedProvider>
84- <UnreadNotifsProvider>
85- <ThemeProvider theme={theme}>
86- {/* All components should be within this provider */}
87- <RootSiblingParent>
88- <GestureHandlerRootView style={s.h100pct}>
89- <TestCtrls />
90- <Shell />
91- </GestureHandlerRootView>
92- </RootSiblingParent>
93- </ThemeProvider>
94- </UnreadNotifsProvider>
95- </SelectedFeedProvider>
96- </LoggedOutViewProvider>
0097 </StatsigProvider>
98 </React.Fragment>
99 </Splash>
···118 * that is set up in the InnerApp component above.
119 */
120 return (
121- <QueryClientProvider client={queryClient}>
00122 <SessionProvider>
123 <ShellStateProvider>
124 <PrefsStateProvider>
···140 </PrefsStateProvider>
141 </ShellStateProvider>
142 </SessionProvider>
143- </QueryClientProvider>
144 )
145}
146
···5import {RootSiblingParent} from 'react-native-root-siblings'
6import * as SplashScreen from 'expo-splash-screen'
7import {GestureHandlerRootView} from 'react-native-gesture-handler'
8+import {PersistQueryClientProvider} from '@tanstack/react-query-persist-client'
9import {
10 SafeAreaProvider,
11 initialWindowMetrics,
···22import {Shell} from 'view/shell'
23import * as notifications from 'lib/notifications/notifications'
24import * as Toast from 'view/com/util/Toast'
25+import {
26+ queryClient,
27+ asyncStoragePersister,
28+ dehydrateOptions,
29+} from 'lib/react-query'
30import {TestCtrls} from 'view/com/testing/TestCtrls'
31import {Provider as ShellStateProvider} from 'state/shell'
32import {Provider as ModalStateProvider} from 'state/modals'
···37import {Provider as PrefsStateProvider} from 'state/preferences'
38import {Provider as LoggedOutViewProvider} from 'state/shell/logged-out'
39import {Provider as SelectedFeedProvider} from 'state/shell/selected-feed'
40+import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
41import I18nProvider from './locale/i18nProvider'
42import {
43 Provider as SessionProvider,
···84 // Resets the entire tree below when it changes:
85 key={currentAccount?.did}>
86 <StatsigProvider>
87+ <LabelDefsProvider>
88+ <LoggedOutViewProvider>
89+ <SelectedFeedProvider>
90+ <UnreadNotifsProvider>
91+ <ThemeProvider theme={theme}>
92+ {/* All components should be within this provider */}
93+ <RootSiblingParent>
94+ <GestureHandlerRootView style={s.h100pct}>
95+ <TestCtrls />
96+ <Shell />
97+ </GestureHandlerRootView>
98+ </RootSiblingParent>
99+ </ThemeProvider>
100+ </UnreadNotifsProvider>
101+ </SelectedFeedProvider>
102+ </LoggedOutViewProvider>
103+ </LabelDefsProvider>
104 </StatsigProvider>
105 </React.Fragment>
106 </Splash>
···125 * that is set up in the InnerApp component above.
126 */
127 return (
128+ <PersistQueryClientProvider
129+ client={queryClient}
130+ persistOptions={{persister: asyncStoragePersister, dehydrateOptions}}>
131 <SessionProvider>
132 <ShellStateProvider>
133 <PrefsStateProvider>
···149 </PrefsStateProvider>
150 </ShellStateProvider>
151 </SessionProvider>
152+ </PersistQueryClientProvider>
153 )
154}
155
+28-19
src/App.web.tsx
···1import 'lib/sentry' // must be near top
23import React, {useState, useEffect} from 'react'
4-import {QueryClientProvider} from '@tanstack/react-query'
5import {SafeAreaProvider} from 'react-native-safe-area-context'
6import {RootSiblingParent} from 'react-native-root-siblings'
7···13import {Shell} from 'view/shell/index'
14import {ToastContainer} from 'view/com/util/Toast.web'
15import {ThemeProvider} from 'lib/ThemeContext'
16-import {queryClient} from 'lib/react-query'
000017import {Provider as ShellStateProvider} from 'state/shell'
18import {Provider as ModalStateProvider} from 'state/modals'
19import {Provider as DialogStateProvider} from 'state/dialogs'
···23import {Provider as PrefsStateProvider} from 'state/preferences'
24import {Provider as LoggedOutViewProvider} from 'state/shell/logged-out'
25import {Provider as SelectedFeedProvider} from 'state/shell/selected-feed'
026import I18nProvider from './locale/i18nProvider'
27import {
28 Provider as SessionProvider,
···56 // Resets the entire tree below when it changes:
57 key={currentAccount?.did}>
58 <StatsigProvider>
59- <LoggedOutViewProvider>
60- <SelectedFeedProvider>
61- <UnreadNotifsProvider>
62- <ThemeProvider theme={theme}>
63- {/* All components should be within this provider */}
64- <RootSiblingParent>
65- <SafeAreaProvider>
66- <Shell />
67- </SafeAreaProvider>
68- </RootSiblingParent>
69- <ToastContainer />
70- </ThemeProvider>
71- </UnreadNotifsProvider>
72- </SelectedFeedProvider>
73- </LoggedOutViewProvider>
0074 </StatsigProvider>
75 </React.Fragment>
76 </Alf>
···93 * that is set up in the InnerApp component above.
94 */
95 return (
96- <QueryClientProvider client={queryClient}>
0097 <SessionProvider>
98 <ShellStateProvider>
99 <PrefsStateProvider>
···115 </PrefsStateProvider>
116 </ShellStateProvider>
117 </SessionProvider>
118- </QueryClientProvider>
119 )
120}
121
···1import 'lib/sentry' // must be near top
23import React, {useState, useEffect} from 'react'
4+import {PersistQueryClientProvider} from '@tanstack/react-query-persist-client'
5import {SafeAreaProvider} from 'react-native-safe-area-context'
6import {RootSiblingParent} from 'react-native-root-siblings'
7···13import {Shell} from 'view/shell/index'
14import {ToastContainer} from 'view/com/util/Toast.web'
15import {ThemeProvider} from 'lib/ThemeContext'
16+import {
17+ queryClient,
18+ asyncStoragePersister,
19+ dehydrateOptions,
20+} from 'lib/react-query'
21import {Provider as ShellStateProvider} from 'state/shell'
22import {Provider as ModalStateProvider} from 'state/modals'
23import {Provider as DialogStateProvider} from 'state/dialogs'
···27import {Provider as PrefsStateProvider} from 'state/preferences'
28import {Provider as LoggedOutViewProvider} from 'state/shell/logged-out'
29import {Provider as SelectedFeedProvider} from 'state/shell/selected-feed'
30+import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
31import I18nProvider from './locale/i18nProvider'
32import {
33 Provider as SessionProvider,
···61 // Resets the entire tree below when it changes:
62 key={currentAccount?.did}>
63 <StatsigProvider>
64+ <LabelDefsProvider>
65+ <LoggedOutViewProvider>
66+ <SelectedFeedProvider>
67+ <UnreadNotifsProvider>
68+ <ThemeProvider theme={theme}>
69+ {/* All components should be within this provider */}
70+ <RootSiblingParent>
71+ <SafeAreaProvider>
72+ <Shell />
73+ </SafeAreaProvider>
74+ </RootSiblingParent>
75+ <ToastContainer />
76+ </ThemeProvider>
77+ </UnreadNotifsProvider>
78+ </SelectedFeedProvider>
79+ </LoggedOutViewProvider>
80+ </LabelDefsProvider>
81 </StatsigProvider>
82 </React.Fragment>
83 </Alf>
···100 * that is set up in the InnerApp component above.
101 */
102 return (
103+ <PersistQueryClientProvider
104+ client={queryClient}
105+ persistOptions={{persister: asyncStoragePersister, dehydrateOptions}}>
106 <SessionProvider>
107 <ShellStateProvider>
108 <PrefsStateProvider>
···124 </PrefsStateProvider>
125 </ShellStateProvider>
126 </SessionProvider>
127+ </PersistQueryClientProvider>
128 )
129}
130
+13-1
src/Navigation.tsx
···46import {FeedsScreen} from './view/screens/Feeds'
47import {NotificationsScreen} from './view/screens/Notifications'
48import {ListsScreen} from './view/screens/Lists'
49-import {ModerationScreen} from './view/screens/Moderation'
50import {ModerationModlistsScreen} from './view/screens/ModerationModlists'
51import {NotFoundScreen} from './view/screens/NotFound'
52import {SettingsScreen} from './view/screens/Settings'
···61import {PostLikedByScreen} from './view/screens/PostLikedBy'
62import {PostRepostedByScreen} from './view/screens/PostRepostedBy'
63import {Storybook} from './view/screens/Storybook'
064import {LogScreen} from './view/screens/Log'
65import {SupportScreen} from './view/screens/Support'
66import {PrivacyPolicyScreen} from './view/screens/PrivacyPolicy'
···78import {msg} from '@lingui/macro'
79import {i18n, MessageDescriptor} from '@lingui/core'
80import HashtagScreen from '#/screens/Hashtag'
081import {logEvent, attachRouteToLogEvents} from './lib/statsig/statsig'
8283const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
···199 options={{title: title(msg`Liked by`)}}
200 />
201 <Stack.Screen
00000202 name="Debug"
203 getComponent={() => Storybook}
204 options={{title: title(msg`Storybook`), requireAuth: true}}
00000205 />
206 <Stack.Screen
207 name="Log"
···46import {FeedsScreen} from './view/screens/Feeds'
47import {NotificationsScreen} from './view/screens/Notifications'
48import {ListsScreen} from './view/screens/Lists'
49+import {ModerationScreen} from '#/screens/Moderation'
50import {ModerationModlistsScreen} from './view/screens/ModerationModlists'
51import {NotFoundScreen} from './view/screens/NotFound'
52import {SettingsScreen} from './view/screens/Settings'
···61import {PostLikedByScreen} from './view/screens/PostLikedBy'
62import {PostRepostedByScreen} from './view/screens/PostRepostedBy'
63import {Storybook} from './view/screens/Storybook'
64+import {DebugModScreen} from './view/screens/DebugMod'
65import {LogScreen} from './view/screens/Log'
66import {SupportScreen} from './view/screens/Support'
67import {PrivacyPolicyScreen} from './view/screens/PrivacyPolicy'
···79import {msg} from '@lingui/macro'
80import {i18n, MessageDescriptor} from '@lingui/core'
81import HashtagScreen from '#/screens/Hashtag'
82+import {ProfileLabelerLikedByScreen} from '#/screens/Profile/ProfileLabelerLikedBy'
83import {logEvent, attachRouteToLogEvents} from './lib/statsig/statsig'
8485const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
···201 options={{title: title(msg`Liked by`)}}
202 />
203 <Stack.Screen
204+ name="ProfileLabelerLikedBy"
205+ getComponent={() => ProfileLabelerLikedByScreen}
206+ options={{title: title(msg`Liked by`)}}
207+ />
208+ <Stack.Screen
209 name="Debug"
210 getComponent={() => Storybook}
211 options={{title: title(msg`Storybook`), requireAuth: true}}
212+ />
213+ <Stack.Screen
214+ name="DebugMod"
215+ getComponent={() => DebugModScreen}
216+ options={{title: title(msg`Moderation states`), requireAuth: true}}
217 />
218 <Stack.Screen
219 name="Log"
···1import React from 'react'
2-import {Text as RNText, TextStyle, TextProps as RNTextProps} from 'react-native'
000003import {UITextView} from 'react-native-ui-text-view'
45import {useTheme, atoms, web, flatten} from '#/alf'
···34 * If the `lineHeight` value is > 2, we assume it's an absolute value and
35 * returns it as-is.
36 */
37-function normalizeTextStyles(styles: TextStyle[]) {
38 const s = flatten(styles)
39 // should always be defined on these components
40 const fontSize = s.fontSize || atoms.text_md.fontSize
···1import React from 'react'
2+import {
3+ Text as RNText,
4+ StyleProp,
5+ TextStyle,
6+ TextProps as RNTextProps,
7+} from 'react-native'
8import {UITextView} from 'react-native-ui-text-view'
910import {useTheme, atoms, web, flatten} from '#/alf'
···39 * If the `lineHeight` value is > 2, we assume it's an absolute value and
40 * returns it as-is.
41 */
42+export function normalizeTextStyles(styles: StyleProp<TextStyle>) {
43 const s = flatten(styles)
44 // should always be defined on these components
45 const fontSize = s.fontSize || atoms.text_md.fontSize
···1-import {LabelPreference} from '@atproto/api'
2-3-/**
4- * Content labels previously included 'show', which has been deprecated in
5- * favor of 'ignore'. The API can return legacy data from the database, and
6- * we clean up the data in `usePreferencesQuery`.
7- *
8- * @deprecated
9- */
10-export function temp__migrateLabelPref(
11- pref: LabelPreference | 'show',
12-): LabelPreference {
13- // @ts-ignore
14- if (pref === 'show') return 'ignore'
15- return pref
16-}
···0000000000000000
-34
src/state/queries/profile-extra-info.ts
···1-import {useQuery} from '@tanstack/react-query'
2-3-import {getAgent} from '#/state/session'
4-import {STALE} from '#/state/queries'
5-6-// TODO refactor invalidate on mutate?
7-export const RQKEY = (did: string) => ['profile-extra-info', did]
8-9-/**
10- * Fetches some additional information for the profile screen which
11- * is not available in the API's ProfileView
12- */
13-export function useProfileExtraInfoQuery(did: string) {
14- return useQuery({
15- staleTime: STALE.MINUTES.ONE,
16- queryKey: RQKEY(did),
17- async queryFn() {
18- const [listsRes, feedsRes] = await Promise.all([
19- getAgent().app.bsky.graph.getLists({
20- actor: did,
21- limit: 1,
22- }),
23- getAgent().app.bsky.feed.getActorFeeds({
24- actor: did,
25- limit: 1,
26- }),
27- ])
28- return {
29- hasLists: listsRes.data.lists.length > 0,
30- hasFeedgens: feedsRes.data.feeds.length > 0,
31- }
32- },
33- })
34-}
···39import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
40import {useExternalLinkFetch} from './useExternalLinkFetch'
41import {isWeb, isNative, isAndroid, isIOS} from 'platform/detection'
42-import QuoteEmbed from '../util/post-embeds/QuoteEmbed'
43import {GalleryModel} from 'state/models/media/gallery'
44import {Gallery} from './photos/Gallery'
45import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
···39import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
40import {useExternalLinkFetch} from './useExternalLinkFetch'
41import {isWeb, isNative, isAndroid, isIOS} from 'platform/detection'
42+import {QuoteEmbed} from '../util/post-embeds/QuoteEmbed'
43import {GalleryModel} from 'state/models/media/gallery'
44import {Gallery} from './photos/Gallery'
45import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
···15import * as ListAddUserModal from './ListAddRemoveUsers'
16import * as AltImageModal from './AltImage'
17import * as EditImageModal from './AltImage'
18-import * as ReportModal from './report/Modal'
19-import * as AppealLabelModal from './AppealLabel'
20import * as DeleteAccountModal from './DeleteAccount'
21import * as ChangeHandleModal from './ChangeHandle'
22import * as InviteCodesModal from './InviteCodes'
23import * as AddAppPassword from './AddAppPasswords'
24-import * as ContentFilteringSettingsModal from './ContentFilteringSettings'
25import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
26import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings'
27-import * as ModerationDetailsModal from './ModerationDetails'
28-import * as BirthDateSettingsModal from './BirthDateSettings'
29import * as VerifyEmailModal from './VerifyEmail'
30import * as ChangeEmailModal from './ChangeEmail'
31import * as ChangePasswordModal from './ChangePassword'
···68 if (activeModal?.name === 'edit-profile') {
69 snapPoints = EditProfileModal.snapPoints
70 element = <EditProfileModal.Component {...activeModal} />
71- } else if (activeModal?.name === 'report') {
72- snapPoints = ReportModal.snapPoints
73- element = <ReportModal.Component {...activeModal} />
74- } else if (activeModal?.name === 'appeal-label') {
75- snapPoints = AppealLabelModal.snapPoints
76- element = <AppealLabelModal.Component {...activeModal} />
77 } else if (activeModal?.name === 'create-or-edit-list') {
78 snapPoints = CreateOrEditListModal.snapPoints
79 element = <CreateOrEditListModal.Component {...activeModal} />
···110 } else if (activeModal?.name === 'add-app-password') {
111 snapPoints = AddAppPassword.snapPoints
112 element = <AddAppPassword.Component />
113- } else if (activeModal?.name === 'content-filtering-settings') {
114- snapPoints = ContentFilteringSettingsModal.snapPoints
115- element = <ContentFilteringSettingsModal.Component />
116 } else if (activeModal?.name === 'content-languages-settings') {
117 snapPoints = ContentLanguagesSettingsModal.snapPoints
118 element = <ContentLanguagesSettingsModal.Component />
119 } else if (activeModal?.name === 'post-languages-settings') {
120 snapPoints = PostLanguagesSettingsModal.snapPoints
121 element = <PostLanguagesSettingsModal.Component />
122- } else if (activeModal?.name === 'moderation-details') {
123- snapPoints = ModerationDetailsModal.snapPoints
124- element = <ModerationDetailsModal.Component {...activeModal} />
125- } else if (activeModal?.name === 'birth-date-settings') {
126- snapPoints = BirthDateSettingsModal.snapPoints
127- element = <BirthDateSettingsModal.Component />
128 } else if (activeModal?.name === 'verify-email') {
129 snapPoints = VerifyEmailModal.snapPoints
130 element = <VerifyEmailModal.Component {...activeModal} />
···15import * as ListAddUserModal from './ListAddRemoveUsers'
16import * as AltImageModal from './AltImage'
17import * as EditImageModal from './AltImage'
0018import * as DeleteAccountModal from './DeleteAccount'
19import * as ChangeHandleModal from './ChangeHandle'
20import * as InviteCodesModal from './InviteCodes'
21import * as AddAppPassword from './AddAppPasswords'
022import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
23import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings'
0024import * as VerifyEmailModal from './VerifyEmail'
25import * as ChangeEmailModal from './ChangeEmail'
26import * as ChangePasswordModal from './ChangePassword'
···63 if (activeModal?.name === 'edit-profile') {
64 snapPoints = EditProfileModal.snapPoints
65 element = <EditProfileModal.Component {...activeModal} />
00000066 } else if (activeModal?.name === 'create-or-edit-list') {
67 snapPoints = CreateOrEditListModal.snapPoints
68 element = <CreateOrEditListModal.Component {...activeModal} />
···99 } else if (activeModal?.name === 'add-app-password') {
100 snapPoints = AddAppPassword.snapPoints
101 element = <AddAppPassword.Component />
000102 } else if (activeModal?.name === 'content-languages-settings') {
103 snapPoints = ContentLanguagesSettingsModal.snapPoints
104 element = <ContentLanguagesSettingsModal.Component />
105 } else if (activeModal?.name === 'post-languages-settings') {
106 snapPoints = PostLanguagesSettingsModal.snapPoints
107 element = <PostLanguagesSettingsModal.Component />
000000108 } else if (activeModal?.name === 'verify-email') {
109 snapPoints = VerifyEmailModal.snapPoints
110 element = <VerifyEmailModal.Component {...activeModal} />
-15
src/view/com/modals/Modal.web.tsx
···8import {useModals, useModalControls} from '#/state/modals'
9import type {Modal as ModalIface} from '#/state/modals'
10import * as EditProfileModal from './EditProfile'
11-import * as ReportModal from './report/Modal'
12-import * as AppealLabelModal from './AppealLabel'
13import * as CreateOrEditListModal from './CreateOrEditList'
14import * as UserAddRemoveLists from './UserAddRemoveLists'
15import * as ListAddUserModal from './ListAddRemoveUsers'
···23import * as ChangeHandleModal from './ChangeHandle'
24import * as InviteCodesModal from './InviteCodes'
25import * as AddAppPassword from './AddAppPasswords'
26-import * as ContentFilteringSettingsModal from './ContentFilteringSettings'
27import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
28import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings'
29-import * as ModerationDetailsModal from './ModerationDetails'
30-import * as BirthDateSettingsModal from './BirthDateSettings'
31import * as VerifyEmailModal from './VerifyEmail'
32import * as ChangeEmailModal from './ChangeEmail'
33import * as ChangePasswordModal from './ChangePassword'
···79 let element
80 if (modal.name === 'edit-profile') {
81 element = <EditProfileModal.Component {...modal} />
82- } else if (modal.name === 'report') {
83- element = <ReportModal.Component {...modal} />
84- } else if (modal.name === 'appeal-label') {
85- element = <AppealLabelModal.Component {...modal} />
86 } else if (modal.name === 'create-or-edit-list') {
87 element = <CreateOrEditListModal.Component {...modal} />
88 } else if (modal.name === 'user-add-remove-lists') {
···105 element = <InviteCodesModal.Component />
106 } else if (modal.name === 'add-app-password') {
107 element = <AddAppPassword.Component />
108- } else if (modal.name === 'content-filtering-settings') {
109- element = <ContentFilteringSettingsModal.Component />
110 } else if (modal.name === 'content-languages-settings') {
111 element = <ContentLanguagesSettingsModal.Component />
112 } else if (modal.name === 'post-languages-settings') {
···115 element = <AltTextImageModal.Component {...modal} />
116 } else if (modal.name === 'edit-image') {
117 element = <EditImageModal.Component {...modal} />
118- } else if (modal.name === 'moderation-details') {
119- element = <ModerationDetailsModal.Component {...modal} />
120- } else if (modal.name === 'birth-date-settings') {
121- element = <BirthDateSettingsModal.Component />
122 } else if (modal.name === 'verify-email') {
123 element = <VerifyEmailModal.Component {...modal} />
124 } else if (modal.name === 'change-email') {
···8import {useModals, useModalControls} from '#/state/modals'
9import type {Modal as ModalIface} from '#/state/modals'
10import * as EditProfileModal from './EditProfile'
0011import * as CreateOrEditListModal from './CreateOrEditList'
12import * as UserAddRemoveLists from './UserAddRemoveLists'
13import * as ListAddUserModal from './ListAddRemoveUsers'
···21import * as ChangeHandleModal from './ChangeHandle'
22import * as InviteCodesModal from './InviteCodes'
23import * as AddAppPassword from './AddAppPasswords'
024import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings'
25import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings'
0026import * as VerifyEmailModal from './VerifyEmail'
27import * as ChangeEmailModal from './ChangeEmail'
28import * as ChangePasswordModal from './ChangePassword'
···74 let element
75 if (modal.name === 'edit-profile') {
76 element = <EditProfileModal.Component {...modal} />
000077 } else if (modal.name === 'create-or-edit-list') {
78 element = <CreateOrEditListModal.Component {...modal} />
79 } else if (modal.name === 'user-add-remove-lists') {
···96 element = <InviteCodesModal.Component />
97 } else if (modal.name === 'add-app-password') {
98 element = <AddAppPassword.Component />
0099 } else if (modal.name === 'content-languages-settings') {
100 element = <ContentLanguagesSettingsModal.Component />
101 } else if (modal.name === 'post-languages-settings') {
···104 element = <AltTextImageModal.Component {...modal} />
105 } else if (modal.name === 'edit-image') {
106 element = <EditImageModal.Component {...modal} />
0000107 } else if (modal.name === 'verify-email') {
108 element = <VerifyEmailModal.Component {...modal} />
109 } else if (modal.name === 'change-email') {
-142
src/view/com/modals/ModerationDetails.tsx
···1-import React from 'react'
2-import {StyleSheet, View} from 'react-native'
3-import {ModerationUI} from '@atproto/api'
4-import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
5-import {s} from 'lib/styles'
6-import {Text} from '../util/text/Text'
7-import {TextLink} from '../util/Link'
8-import {usePalette} from 'lib/hooks/usePalette'
9-import {isWeb} from 'platform/detection'
10-import {listUriToHref} from 'lib/strings/url-helpers'
11-import {Button} from '../util/forms/Button'
12-import {useModalControls} from '#/state/modals'
13-import {useLingui} from '@lingui/react'
14-import {Trans, msg} from '@lingui/macro'
15-16-export const snapPoints = [300]
17-18-export function Component({
19- context,
20- moderation,
21-}: {
22- context: 'account' | 'content'
23- moderation: ModerationUI
24-}) {
25- const {closeModal} = useModalControls()
26- const {isMobile} = useWebMediaQueries()
27- const pal = usePalette('default')
28- const {_} = useLingui()
29-30- let name
31- let description
32- if (!moderation.cause) {
33- name = _(msg`Content Warning`)
34- description = _(
35- msg`Moderator has chosen to set a general warning on the content.`,
36- )
37- } else if (moderation.cause.type === 'blocking') {
38- if (moderation.cause.source.type === 'list') {
39- const list = moderation.cause.source.list
40- name = _(msg`User Blocked by List`)
41- description = (
42- <Trans>
43- This user is included in the{' '}
44- <TextLink
45- type="2xl"
46- href={listUriToHref(list.uri)}
47- text={list.name}
48- style={pal.link}
49- />{' '}
50- list which you have blocked.
51- </Trans>
52- )
53- } else {
54- name = _(msg`User Blocked`)
55- description = _(
56- msg`You have blocked this user. You cannot view their content.`,
57- )
58- }
59- } else if (moderation.cause.type === 'blocked-by') {
60- name = _(msg`User Blocks You`)
61- description = _(
62- msg`This user has blocked you. You cannot view their content.`,
63- )
64- } else if (moderation.cause.type === 'block-other') {
65- name = _(msg`Content Not Available`)
66- description = _(
67- msg`This content is not available because one of the users involved has blocked the other.`,
68- )
69- } else if (moderation.cause.type === 'muted') {
70- if (moderation.cause.source.type === 'list') {
71- const list = moderation.cause.source.list
72- name = _(msg`Account Muted by List`)
73- description = (
74- <Trans>
75- This user is included in the{' '}
76- <TextLink
77- type="2xl"
78- href={listUriToHref(list.uri)}
79- text={list.name}
80- style={pal.link}
81- />{' '}
82- list which you have muted.
83- </Trans>
84- )
85- } else {
86- name = _(msg`Account Muted`)
87- description = _(msg`You have muted this user.`)
88- }
89- } else {
90- name = moderation.cause.labelDef.strings[context].en.name
91- description = moderation.cause.labelDef.strings[context].en.description
92- }
93-94- return (
95- <View
96- testID="moderationDetailsModal"
97- style={[
98- styles.container,
99- {
100- paddingHorizontal: isMobile ? 14 : 0,
101- },
102- pal.view,
103- ]}>
104- <Text type="title-xl" style={[pal.text, styles.title]}>
105- {name}
106- </Text>
107- <Text type="2xl" style={[pal.text, styles.description]}>
108- {description}
109- </Text>
110- <View style={s.flex1} />
111- <Button
112- type="primary"
113- style={styles.btn}
114- onPress={() => {
115- closeModal()
116- }}>
117- <Text type="button-lg" style={[pal.textLight, s.textCenter, s.white]}>
118- Okay
119- </Text>
120- </Button>
121- </View>
122- )
123-}
124-125-const styles = StyleSheet.create({
126- container: {
127- flex: 1,
128- },
129- title: {
130- textAlign: 'center',
131- fontWeight: 'bold',
132- marginBottom: 12,
133- },
134- description: {
135- textAlign: 'center',
136- },
137- btn: {
138- paddingVertical: 14,
139- marginTop: isWeb ? 40 : 0,
140- marginBottom: isWeb ? 0 : 40,
141- },
142-})
···1-// TODO: ATM, @atproto/api does not export ids but it does have these listed at @atproto/api/client/lexicons
2-// once we start exporting the ids from the @atproto/ap package, replace these hardcoded ones
3-export enum CollectionId {
4- FeedGenerator = 'app.bsky.feed.generator',
5- Profile = 'app.bsky.actor.profile',
6- List = 'app.bsky.graph.list',
7- Post = 'app.bsky.feed.post',
8-}