Remove deprecated models and mobx usage (react-query refactor) (#1934)

* Update login page to use service query

* Update modal to use session instead of store

* Move image sizes cache off store

* Update settings to no longer use store

* Update link-meta fetch to use agent instead of rootstore

* Remove deprecated resolveName()

* Delete deprecated link-metas cache

* Delete deprecated posts cache

* Delete all remaining mobx models, including the root store

* Strip out unused mobx observer wrappers
This commit is contained in:
Paul Frazee 2023-11-16 12:53:43 -08:00 committed by GitHub
parent e637798e05
commit 54faa7e176
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
81 changed files with 1084 additions and 1941 deletions

View file

@ -1,6 +1,5 @@
import React from 'react'
import {SafeAreaView} from 'react-native'
import {observer} from 'mobx-react-lite'
import {Login} from 'view/com/auth/login/Login'
import {CreateAccount} from 'view/com/auth/create/CreateAccount'
import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
@ -16,7 +15,7 @@ enum ScreenState {
S_CreateAccount,
}
export const LoggedOut = observer(function LoggedOutImpl() {
export function LoggedOut() {
const pal = usePalette('default')
const setMinimalShellMode = useSetMinimalShellMode()
const {screen} = useAnalytics()
@ -58,4 +57,4 @@ export const LoggedOut = observer(function LoggedOutImpl() {
</ErrorBoundary>
</SafeAreaView>
)
})
}

View file

@ -1,6 +1,5 @@
import React from 'react'
import {SafeAreaView} from 'react-native'
import {observer} from 'mobx-react-lite'
import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
@ -10,7 +9,7 @@ import {RecommendedFollows} from './onboarding/RecommendedFollows'
import {useSetMinimalShellMode} from '#/state/shell/minimal-mode'
import {useOnboardingState, useOnboardingDispatch} from '#/state/shell'
export const Onboarding = observer(function OnboardingImpl() {
export function Onboarding() {
const pal = usePalette('default')
const setMinimalShellMode = useSetMinimalShellMode()
const onboardingState = useOnboardingState()
@ -38,4 +37,4 @@ export const Onboarding = observer(function OnboardingImpl() {
</ErrorBoundary>
</SafeAreaView>
)
})
}

View file

@ -4,12 +4,14 @@ import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {ComAtprotoServerDescribeServer} from '@atproto/api'
import {TextLink} from '../../util/Link'
import {Text} from '../../util/text/Text'
import {s, colors} from 'lib/styles'
import {ServiceDescription} from 'state/models/session'
import {usePalette} from 'lib/hooks/usePalette'
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
export const Policies = ({
serviceDescription,
needsGuardian,

View file

@ -13,7 +13,7 @@ import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'state/index'
import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'lib/constants'
import {LOGIN_INCLUDE_DEV_SERVERS} from 'lib/build-flags'
/** STEP 1: Your hosting provider

View file

@ -9,13 +9,13 @@ import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {ComAtprotoServerDescribeServer} from '@atproto/api'
import * as EmailValidator from 'email-validator'
import {BskyAgent} from '@atproto/api'
import {useAnalytics} from 'lib/analytics/analytics'
import {Text} from '../../util/text/Text'
import {s} from 'lib/styles'
import {toNiceDomain} from 'lib/strings/url-helpers'
import {ServiceDescription} from 'state/models/session'
import {isNetworkError} from 'lib/strings/errors'
import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext'
@ -26,6 +26,8 @@ import {useLingui} from '@lingui/react'
import {styles} from './styles'
import {useModalControls} from '#/state/modals'
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
export const ForgotPasswordForm = ({
error,
serviceUrl,

View file

@ -2,8 +2,7 @@ import React, {useState, useEffect} from 'react'
import {KeyboardAvoidingView} from 'react-native'
import {useAnalytics} from 'lib/analytics/analytics'
import {LoggedOutLayout} from 'view/com/util/layouts/LoggedOutLayout'
import {useStores, DEFAULT_SERVICE} from 'state/index'
import {ServiceDescription} from 'state/models/session'
import {DEFAULT_SERVICE} from '#/lib/constants'
import {usePalette} from 'lib/hooks/usePalette'
import {logger} from '#/logger'
import {ChooseAccountForm} from './ChooseAccountForm'
@ -14,6 +13,7 @@ import {PasswordUpdatedForm} from './PasswordUpdatedForm'
import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
import {useSession, SessionAccount} from '#/state/session'
import {useServiceQuery} from '#/state/queries/service'
enum Forms {
Login,
@ -25,20 +25,20 @@ enum Forms {
export const Login = ({onPressBack}: {onPressBack: () => void}) => {
const pal = usePalette('default')
const store = useStores()
const {accounts} = useSession()
const {track} = useAnalytics()
const {_} = useLingui()
const [error, setError] = useState<string>('')
const [retryDescribeTrigger, setRetryDescribeTrigger] = useState<any>({})
const [serviceUrl, setServiceUrl] = useState<string>(DEFAULT_SERVICE)
const [serviceDescription, setServiceDescription] = useState<
ServiceDescription | undefined
>(undefined)
const [initialHandle, setInitialHandle] = useState<string>('')
const [currentForm, setCurrentForm] = useState<Forms>(
accounts.length ? Forms.ChooseAccount : Forms.Login,
)
const {
data: serviceDescription,
error: serviceError,
refetch: refetchService,
} = useServiceQuery(serviceUrl)
const onSelectAccount = (account?: SessionAccount) => {
if (account?.service) {
@ -54,35 +54,21 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
}
useEffect(() => {
let aborted = false
setError('')
store.session.describeService(serviceUrl).then(
desc => {
if (aborted) {
return
}
setServiceDescription(desc)
},
err => {
if (aborted) {
return
}
logger.warn(`Failed to fetch service description for ${serviceUrl}`, {
error: err,
})
setError(
_(
msg`Unable to contact your service. Please check your Internet connection.`,
),
)
},
)
return () => {
aborted = true
if (serviceError) {
setError(
_(
msg`Unable to contact your service. Please check your Internet connection.`,
),
)
logger.warn(`Failed to fetch service description for ${serviceUrl}`, {
error: String(serviceError),
})
} else {
setError('')
}
}, [store.session, serviceUrl, retryDescribeTrigger, _])
}, [serviceError, serviceUrl, _])
const onPressRetryConnect = () => setRetryDescribeTrigger({})
const onPressRetryConnect = () => refetchService()
const onPressForgotPassword = () => {
track('Signin:PressedForgotPassword')
setCurrentForm(Forms.ForgotPassword)

View file

@ -10,12 +10,12 @@ import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {ComAtprotoServerDescribeServer} from '@atproto/api'
import {useAnalytics} from 'lib/analytics/analytics'
import {Text} from '../../util/text/Text'
import {s} from 'lib/styles'
import {createFullHandle} from 'lib/strings/handles'
import {toNiceDomain} from 'lib/strings/url-helpers'
import {ServiceDescription} from 'state/models/session'
import {isNetworkError} from 'lib/strings/errors'
import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext'
@ -27,6 +27,8 @@ import {styles} from './styles'
import {useLingui} from '@lingui/react'
import {useModalControls} from '#/state/modals'
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
export const LoginForm = ({
error,
serviceUrl,

View file

@ -1,6 +1,5 @@
import React from 'react'
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {TabletOrDesktop, Mobile} from 'view/com/util/layouts/Breakpoints'
import {Text} from 'view/com/util/text/Text'
@ -16,9 +15,7 @@ import {useSuggestedFeedsQuery} from '#/state/queries/suggested-feeds'
type Props = {
next: () => void
}
export const RecommendedFeeds = observer(function RecommendedFeedsImpl({
next,
}: Props) {
export function RecommendedFeeds({next}: Props) {
const pal = usePalette('default')
const {isTabletOrMobile} = useWebMediaQueries()
const {isLoading, data} = useSuggestedFeedsQuery()
@ -146,7 +143,7 @@ export const RecommendedFeeds = observer(function RecommendedFeedsImpl({
</Mobile>
</>
)
})
}
const tdStyles = StyleSheet.create({
container: {

View file

@ -1,6 +1,5 @@
import React from 'react'
import {View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {AppBskyFeedDefs, RichText as BskRichText} from '@atproto/api'
import {Text} from 'view/com/util/text/Text'
@ -19,7 +18,7 @@ import {
} from '#/state/queries/preferences'
import {logger} from '#/logger'
export const RecommendedFeedsItem = observer(function RecommendedFeedsItemImpl({
export function RecommendedFeedsItem({
item,
}: {
item: AppBskyFeedDefs.GeneratorView
@ -164,4 +163,4 @@ export const RecommendedFeedsItem = observer(function RecommendedFeedsItemImpl({
</View>
</View>
)
})
}

View file

@ -1,6 +1,5 @@
import React from 'react'
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {AppBskyActorDefs, moderateProfile} from '@atproto/api'
import {TabletOrDesktop, Mobile} from 'view/com/util/layouts/Breakpoints'
@ -19,9 +18,7 @@ import {logger} from '#/logger'
type Props = {
next: () => void
}
export const RecommendedFollows = observer(function RecommendedFollowsImpl({
next,
}: Props) {
export function RecommendedFollows({next}: Props) {
const pal = usePalette('default')
const {isTabletOrMobile} = useWebMediaQueries()
const {data: suggestedFollows, dataUpdatedAt} = useSuggestedFollowsQuery()
@ -211,7 +208,7 @@ export const RecommendedFollows = observer(function RecommendedFollowsImpl({
</Mobile>
</>
)
})
}
const tdStyles = StyleSheet.create({
container: {

View file

@ -7,16 +7,13 @@ import {usePalette} from 'lib/hooks/usePalette'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {TitleColumnLayout} from 'view/com/util/layouts/TitleColumnLayout'
import {Button} from 'view/com/util/forms/Button'
import {observer} from 'mobx-react-lite'
type Props = {
next: () => void
skip: () => void
}
export const WelcomeDesktop = observer(function WelcomeDesktopImpl({
next,
}: Props) {
export function WelcomeDesktop({next}: Props) {
const pal = usePalette('default')
const horizontal = useMediaQuery({minWidth: 1300})
const title = (
@ -105,7 +102,7 @@ export const WelcomeDesktop = observer(function WelcomeDesktopImpl({
</View>
</TitleColumnLayout>
)
})
}
const styles = StyleSheet.create({
row: {

View file

@ -5,7 +5,6 @@ import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Button} from 'view/com/util/forms/Button'
import {observer} from 'mobx-react-lite'
import {ViewHeader} from 'view/com/util/ViewHeader'
import {Trans} from '@lingui/macro'
@ -14,10 +13,7 @@ type Props = {
skip: () => void
}
export const WelcomeMobile = observer(function WelcomeMobileImpl({
next,
skip,
}: Props) {
export function WelcomeMobile({next, skip}: Props) {
const pal = usePalette('default')
return (
@ -102,7 +98,7 @@ export const WelcomeMobile = observer(function WelcomeMobileImpl({
/>
</View>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -5,7 +5,6 @@ import {
StyleSheet,
TouchableOpacity,
} from 'react-native'
import {observer} from 'mobx-react-lite'
import {CenteredView} from '../util/Views'
import {LoggedOut} from './LoggedOut'
import {Onboarding} from './Onboarding'
@ -18,7 +17,7 @@ import {useSession} from '#/state/session'
export const withAuthRequired = <P extends object>(
Component: React.ComponentType<P>,
): React.FC<P> =>
observer(function AuthRequired(props: P) {
function AuthRequired(props: P) {
const {isInitialLoad, hasSession} = useSession()
const onboardingState = useOnboardingState()
if (isInitialLoad) {
@ -31,7 +30,7 @@ export const withAuthRequired = <P extends object>(
return <Onboarding />
}
return <Component {...props} />
})
}
function Loading() {
const pal = usePalette('default')

View file

@ -1,6 +1,5 @@
import React from 'react'
import {Keyboard, StyleSheet} from 'react-native'
import {observer} from 'mobx-react-lite'
import {Button} from 'view/com/util/forms/Button'
import {usePalette} from 'lib/hooks/usePalette'
import {ShieldExclamation} from 'lib/icons'
@ -11,7 +10,7 @@ import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
import {useModalControls} from '#/state/modals'
export const LabelsBtn = observer(function LabelsBtn({
export function LabelsBtn({
labels,
hasMedia,
onChange,
@ -49,7 +48,7 @@ export const LabelsBtn = observer(function LabelsBtn({
) : null}
</Button>
)
})
}
const styles = StyleSheet.create({
button: {

View file

@ -1,6 +1,5 @@
import React, {useCallback, useMemo} from 'react'
import {StyleSheet, Keyboard} from 'react-native'
import {observer} from 'mobx-react-lite'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
@ -24,7 +23,7 @@ import {
import {t, msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
export const SelectLangBtn = observer(function SelectLangBtn() {
export function SelectLangBtn() {
const pal = usePalette('default')
const {_} = useLingui()
const {openModal} = useModalControls()
@ -117,7 +116,7 @@ export const SelectLangBtn = observer(function SelectLangBtn() {
)}
</DropdownButton>
)
})
}
const styles = StyleSheet.create({
button: {

View file

@ -1,6 +1,5 @@
import React, {useEffect, useRef} from 'react'
import {Animated, TouchableOpacity, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from 'view/com/util/text/Text'
@ -10,7 +9,7 @@ import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
import {Trans} from '@lingui/macro'
import {AppBskyActorDefs} from '@atproto/api'
export const Autocomplete = observer(function AutocompleteImpl({
export function Autocomplete({
prefix,
onSelect,
}: {
@ -103,7 +102,7 @@ export const Autocomplete = observer(function AutocompleteImpl({
) : null}
</Animated.View>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -1,5 +1,4 @@
import {useState, useEffect} from 'react'
import {useStores} from 'state/index'
import {ImageModel} from 'state/models/media/image'
import * as apilib from 'lib/api/index'
import {getLinkMeta} from 'lib/link-meta/link-meta'
@ -17,6 +16,7 @@ import {
import {ComposerOpts} from 'state/shell/composer'
import {POST_IMG_MAX} from 'lib/constants'
import {logger} from '#/logger'
import {useSession} from '#/state/session'
import {useGetPost} from '#/state/queries/post'
export function useExternalLinkFetch({
@ -24,7 +24,7 @@ export function useExternalLinkFetch({
}: {
setQuote: (opts: ComposerOpts['quote']) => void
}) {
const store = useStores()
const {agent} = useSession()
const [extLink, setExtLink] = useState<apilib.ExternalEmbedDraft | undefined>(
undefined,
)
@ -56,7 +56,7 @@ export function useExternalLinkFetch({
},
)
} else if (isBskyCustomFeedUrl(extLink.uri)) {
getFeedAsEmbed(store, extLink.uri).then(
getFeedAsEmbed(agent, extLink.uri).then(
({embed, meta}) => {
if (aborted) {
return
@ -74,7 +74,7 @@ export function useExternalLinkFetch({
},
)
} else if (isBskyListUrl(extLink.uri)) {
getListAsEmbed(store, extLink.uri).then(
getListAsEmbed(agent, extLink.uri).then(
({embed, meta}) => {
if (aborted) {
return
@ -92,7 +92,7 @@ export function useExternalLinkFetch({
},
)
} else {
getLinkMeta(store, extLink.uri).then(meta => {
getLinkMeta(agent, extLink.uri).then(meta => {
if (aborted) {
return
}
@ -134,7 +134,7 @@ export function useExternalLinkFetch({
})
}
return cleanup
}, [store, extLink, setQuote, getPost])
}, [agent, extLink, setQuote, getPost])
return {extLink, setExtLink}
}

View file

@ -315,7 +315,6 @@ const ImageItem = ({
<GestureDetector gesture={composedGesture}>
<AnimatedImage
contentFit="contain"
// NOTE: Don't pass imageSrc={imageSrc} or MobX will break.
source={{uri: imageSrc.uri}}
style={[styles.image, animatedStyle]}
accessibilityLabel={imageSrc.alt}

View file

@ -139,7 +139,6 @@ const ImageItem = ({imageSrc, onTap, onZoom, onRequestClose}: Props) => {
{(!loaded || !imageDimensions) && <ImageLoading />}
<AnimatedImage
contentFit="contain"
// NOTE: Don't pass imageSrc={imageSrc} or MobX will break.
source={{uri: imageSrc.uri}}
style={[styles.image, animatedStyle]}
accessibilityLabel={imageSrc.alt}

View file

@ -5,7 +5,6 @@ import {
TouchableOpacity,
View,
} from 'react-native'
import {observer} from 'mobx-react-lite'
import {Text} from '../util/text/Text'
import {DateInput} from '../util/forms/DateInput'
import {ErrorMessage} from '../util/error/ErrorMessage'
@ -103,7 +102,7 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
)
}
export const Component = observer(function Component({}: {}) {
export function Component({}: {}) {
const {data: preferences} = usePreferencesQuery()
return !preferences ? (
@ -111,7 +110,7 @@ export const Component = observer(function Component({}: {}) {
) : (
<Inner preferences={preferences} />
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -1,7 +1,6 @@
import React, {useState} from 'react'
import {ActivityIndicator, SafeAreaView, StyleSheet, View} from 'react-native'
import {ScrollView, TextInput} from './util'
import {observer} from 'mobx-react-lite'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
import {ErrorMessage} from '../util/error/ErrorMessage'
@ -24,7 +23,7 @@ enum Stages {
export const snapPoints = ['90%']
export const Component = observer(function Component({}: {}) {
export function Component() {
const pal = usePalette('default')
const {agent, currentAccount} = useSession()
const {updateCurrentAccount} = useSessionApi()
@ -226,7 +225,7 @@ export const Component = observer(function Component({}: {}) {
</ScrollView>
</SafeAreaView>
)
})
}
const styles = StyleSheet.create({
titleSection: {

View file

@ -2,7 +2,6 @@ import React from 'react'
import {LabelPreference} from '@atproto/api'
import {StyleSheet, Pressable, View} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'
import {observer} from 'mobx-react-lite'
import {ScrollView} from './util'
import {s, colors, gradients} from 'lib/styles'
import {Text} from '../util/text/Text'
@ -28,82 +27,80 @@ import {
export const snapPoints = ['90%']
export const Component = observer(
function ContentFilteringSettingsImpl({}: {}) {
const {isMobile} = useWebMediaQueries()
const pal = usePalette('default')
const {_} = useLingui()
const {closeModal} = useModalControls()
const {data: preferences} = usePreferencesQuery()
export function Component({}: {}) {
const {isMobile} = useWebMediaQueries()
const pal = usePalette('default')
const {_} = useLingui()
const {closeModal} = useModalControls()
const {data: preferences} = usePreferencesQuery()
const onPressDone = React.useCallback(() => {
closeModal()
}, [closeModal])
const onPressDone = React.useCallback(() => {
closeModal()
}, [closeModal])
return (
<View testID="contentFilteringModal" style={[pal.view, styles.container]}>
<Text style={[pal.text, styles.title]}>
<Trans>Content Filtering</Trans>
</Text>
return (
<View testID="contentFilteringModal" style={[pal.view, styles.container]}>
<Text style={[pal.text, styles.title]}>
<Trans>Content Filtering</Trans>
</Text>
<ScrollView style={styles.scrollContainer}>
<AdultContentEnabledPref />
<ContentLabelPref
preferences={preferences}
labelGroup="nsfw"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref
preferences={preferences}
labelGroup="nudity"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref
preferences={preferences}
labelGroup="suggestive"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref
preferences={preferences}
labelGroup="gore"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref preferences={preferences} labelGroup="hate" />
<ContentLabelPref preferences={preferences} labelGroup="spam" />
<ContentLabelPref
preferences={preferences}
labelGroup="impersonation"
/>
<View style={{height: isMobile ? 60 : 0}} />
</ScrollView>
<ScrollView style={styles.scrollContainer}>
<AdultContentEnabledPref />
<ContentLabelPref
preferences={preferences}
labelGroup="nsfw"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref
preferences={preferences}
labelGroup="nudity"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref
preferences={preferences}
labelGroup="suggestive"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref
preferences={preferences}
labelGroup="gore"
disabled={!preferences?.adultContentEnabled}
/>
<ContentLabelPref preferences={preferences} labelGroup="hate" />
<ContentLabelPref preferences={preferences} labelGroup="spam" />
<ContentLabelPref
preferences={preferences}
labelGroup="impersonation"
/>
<View style={{height: isMobile ? 60 : 0}} />
</ScrollView>
<View
style={[
styles.btnContainer,
isMobile && styles.btnContainerMobile,
pal.borderDark,
]}>
<Pressable
testID="sendReportBtn"
onPress={onPressDone}
accessibilityRole="button"
accessibilityLabel={_(msg`Done`)}
accessibilityHint="">
<LinearGradient
colors={[gradients.blueLight.start, gradients.blueLight.end]}
start={{x: 0, y: 0}}
end={{x: 1, y: 1}}
style={[styles.btn]}>
<Text style={[s.white, s.bold, s.f18]}>
<Trans>Done</Trans>
</Text>
</LinearGradient>
</Pressable>
</View>
<View
style={[
styles.btnContainer,
isMobile && styles.btnContainerMobile,
pal.borderDark,
]}>
<Pressable
testID="sendReportBtn"
onPress={onPressDone}
accessibilityRole="button"
accessibilityLabel={_(msg`Done`)}
accessibilityHint="">
<LinearGradient
colors={[gradients.blueLight.start, gradients.blueLight.end]}
start={{x: 0, y: 0}}
end={{x: 1, y: 1}}
style={[styles.btn]}>
<Text style={[s.white, s.bold, s.f18]}>
<Trans>Done</Trans>
</Text>
</LinearGradient>
</Pressable>
</View>
)
},
)
</View>
)
}
function AdultContentEnabledPref() {
const pal = usePalette('default')
@ -171,7 +168,7 @@ function AdultContentEnabledPref() {
}
// TODO: Refactor this component to pass labels down to each tab
const ContentLabelPref = observer(function ContentLabelPrefImpl({
function ContentLabelPref({
preferences,
labelGroup,
disabled,
@ -217,7 +214,7 @@ const ContentLabelPref = observer(function ContentLabelPrefImpl({
)}
</View>
)
})
}
interface SelectGroupProps {
current: LabelPreference

View file

@ -5,7 +5,6 @@ import {
View,
ActivityIndicator,
} from 'react-native'
import {observer} from 'mobx-react-lite'
import {ComAtprotoServerDefs} from '@atproto/api'
import {
FontAwesomeIcon,
@ -129,7 +128,7 @@ export function Inner({invites}: {invites: InviteCodesQueryResponse}) {
)
}
const InviteCode = observer(function InviteCodeImpl({
function InviteCode({
testID,
invite,
used,
@ -211,7 +210,7 @@ const InviteCode = observer(function InviteCodeImpl({
) : null}
</View>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -1,7 +1,6 @@
import React from 'react'
import {Linking, SafeAreaView, StyleSheet, View} from 'react-native'
import {ScrollView} from './util'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
@ -16,13 +15,7 @@ import {useModalControls} from '#/state/modals'
export const snapPoints = ['50%']
export const Component = observer(function Component({
text,
href,
}: {
text: string
href: string
}) {
export function Component({text, href}: {text: string; href: string}) {
const pal = usePalette('default')
const {closeModal} = useModalControls()
const {isMobile} = useWebMediaQueries()
@ -97,7 +90,7 @@ export const Component = observer(function Component({
</ScrollView>
</SafeAreaView>
)
})
}
function LinkBox({href}: {href: string}) {
const pal = usePalette('default')

View file

@ -1,7 +1,6 @@
import React, {useRef, useEffect} from 'react'
import {StyleSheet} from 'react-native'
import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'
import {observer} from 'mobx-react-lite'
import BottomSheet from '@gorhom/bottom-sheet'
import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop'
import {usePalette} from 'lib/hooks/usePalette'
@ -40,7 +39,7 @@ import * as LinkWarningModal from './LinkWarning'
const DEFAULT_SNAPPOINTS = ['90%']
const HANDLE_HEIGHT = 24
export const ModalsContainer = observer(function ModalsContainer() {
export function ModalsContainer() {
const {isModalActive, activeModals} = useModals()
const {closeModal} = useModalControls()
const bottomSheetRef = useRef<BottomSheet>(null)
@ -198,7 +197,7 @@ export const ModalsContainer = observer(function ModalsContainer() {
{element}
</BottomSheet>
)
})
}
const styles = StyleSheet.create({
handle: {

View file

@ -1,6 +1,5 @@
import React from 'react'
import {TouchableWithoutFeedback, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import type {Modal as ModalIface} from '#/state/modals'
@ -33,7 +32,7 @@ import * as VerifyEmailModal from './VerifyEmail'
import * as ChangeEmailModal from './ChangeEmail'
import * as LinkWarningModal from './LinkWarning'
export const ModalsContainer = observer(function ModalsContainer() {
export function ModalsContainer() {
const {isModalActive, activeModals} = useModals()
if (!isModalActive) {
@ -47,7 +46,7 @@ export const ModalsContainer = observer(function ModalsContainer() {
))}
</>
)
})
}
function Modal({modal}: {modal: ModalIface}) {
const {isModalActive} = useModals()

View file

@ -1,6 +1,5 @@
import React, {useState} from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {Text} from '../util/text/Text'
import {s, colors} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
@ -17,7 +16,7 @@ const ADULT_CONTENT_LABELS = ['sexual', 'nudity', 'porn']
export const snapPoints = ['50%']
export const Component = observer(function Component({
export function Component({
labels,
hasMedia,
onChange,
@ -161,7 +160,7 @@ export const Component = observer(function Component({
</View>
</View>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -9,7 +9,7 @@ import {Text} from '../util/text/Text'
import {s, colors} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext'
import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'state/index'
import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'lib/constants'
import {LOGIN_INCLUDE_DEV_SERVERS} from 'lib/build-flags'
import {Trans, msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'

View file

@ -8,7 +8,6 @@ import {
} from 'react-native'
import {Svg, Circle, Path} from 'react-native-svg'
import {ScrollView, TextInput} from './util'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
@ -32,11 +31,7 @@ enum Stages {
ConfirmCode,
}
export const Component = observer(function Component({
showReminder,
}: {
showReminder?: boolean
}) {
export function Component({showReminder}: {showReminder?: boolean}) {
const pal = usePalette('default')
const {agent, currentAccount} = useSession()
const {updateCurrentAccount} = useSessionApi()
@ -244,7 +239,7 @@ export const Component = observer(function Component({
</ScrollView>
</SafeAreaView>
)
})
}
function ReminderIllustration() {
const pal = usePalette('default')

View file

@ -1,11 +1,10 @@
import React from 'react'
import {StyleSheet} from 'react-native'
import {usePalette} from 'lib/hooks/usePalette'
import {observer} from 'mobx-react-lite'
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
import {useLanguagePrefs, toPostLanguages} from '#/state/preferences/languages'
export const LanguageToggle = observer(function LanguageToggleImpl({
export function LanguageToggle({
code2,
name,
onPress,
@ -39,7 +38,7 @@ export const LanguageToggle = observer(function LanguageToggleImpl({
style={[pal.border, styles.languageToggle, isDisabled && styles.dimmed]}
/>
)
})
}
const styles = StyleSheet.create({
languageToggle: {

View file

@ -1,6 +1,5 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {ScrollView} from '../util'
import {Text} from '../../util/text/Text'
import {usePalette} from 'lib/hooks/usePalette'
@ -19,7 +18,7 @@ import {
export const snapPoints = ['100%']
export const Component = observer(function PostLanguagesSettingsImpl() {
export function Component() {
const {closeModal} = useModalControls()
const langPrefs = useLanguagePrefs()
const setLangPrefs = useLanguagePrefsApi()
@ -111,7 +110,7 @@ export const Component = observer(function PostLanguagesSettingsImpl() {
<ConfirmLanguagesButton onPress={onPressDone} />
</View>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -2,7 +2,6 @@ import React, {useState, useMemo} from 'react'
import {Linking, StyleSheet, TouchableOpacity, View} from 'react-native'
import {ScrollView} from 'react-native-gesture-handler'
import {AtUri} from '@atproto/api'
import {useStores} from 'state/index'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {s} from 'lib/styles'
import {Text} from '../../util/text/Text'
@ -17,6 +16,7 @@ import {CollectionId} from './types'
import {Trans, msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useModalControls} from '#/state/modals'
import {useSession} from '#/state/session'
const DMCA_LINK = 'https://blueskyweb.xyz/support/copyright'
@ -39,7 +39,7 @@ type ReportComponentProps =
}
export function Component(content: ReportComponentProps) {
const store = useStores()
const {agent} = useSession()
const {closeModal} = useModalControls()
const pal = usePalette('default')
const {isMobile} = useWebMediaQueries()
@ -70,7 +70,7 @@ export function Component(content: ReportComponentProps) {
const $type = !isAccountReport
? 'com.atproto.repo.strongRef'
: 'com.atproto.admin.defs#repoRef'
await store.agent.createModerationReport({
await agent.createModerationReport({
reasonType: issue,
subject: {
$type,

View file

@ -1,7 +1,6 @@
import React from 'react'
import {StyleSheet} from 'react-native'
import Animated from 'react-native-reanimated'
import {observer} from 'mobx-react-lite'
import {TabBar} from 'view/com/pager/TabBar'
import {RenderTabBarFnProps} from 'view/com/pager/Pager'
import {usePalette} from 'lib/hooks/usePalette'
@ -11,7 +10,7 @@ import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
import {useShellLayout} from '#/state/shell/shell-layout'
import {usePinnedFeedsInfos} from '#/state/queries/feed'
export const FeedsTabBar = observer(function FeedsTabBarImpl(
export function FeedsTabBar(
props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void},
) {
const {isMobile, isTablet} = useWebMediaQueries()
@ -22,9 +21,9 @@ export const FeedsTabBar = observer(function FeedsTabBarImpl(
} else {
return null
}
})
}
const FeedsTabBarTablet = observer(function FeedsTabBarTabletImpl(
function FeedsTabBarTablet(
props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void},
) {
const feeds = usePinnedFeedsInfos()
@ -48,7 +47,7 @@ const FeedsTabBarTablet = observer(function FeedsTabBarTabletImpl(
/>
</Animated.View>
)
})
}
const styles = StyleSheet.create({
tabBar: {

View file

@ -1,6 +1,5 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {TabBar} from 'view/com/pager/TabBar'
import {RenderTabBarFnProps} from 'view/com/pager/Pager'
import {usePalette} from 'lib/hooks/usePalette'
@ -20,7 +19,7 @@ import {useShellLayout} from '#/state/shell/shell-layout'
import {useSession} from '#/state/session'
import {usePinnedFeedsInfos} from '#/state/queries/feed'
export const FeedsTabBar = observer(function FeedsTabBarImpl(
export function FeedsTabBar(
props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void},
) {
const pal = usePalette('default')
@ -88,7 +87,7 @@ export const FeedsTabBar = observer(function FeedsTabBarImpl(
/>
</Animated.View>
)
})
}
const styles = StyleSheet.create({
tabBar: {

View file

@ -1,6 +1,5 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FeedPostSlice} from '#/state/queries/post-feed'
import {AtUri, moderatePost, ModerationOpts} from '@atproto/api'
import {Link} from '../util/Link'
@ -10,7 +9,7 @@ import {FeedItem} from './FeedItem'
import {usePalette} from 'lib/hooks/usePalette'
import {makeProfileLink} from 'lib/routes/links'
export const FeedSlice = observer(function FeedSliceImpl({
export function FeedSlice({
slice,
dataUpdatedAt,
ignoreFilterFor,
@ -94,7 +93,7 @@ export const FeedSlice = observer(function FeedSliceImpl({
))}
</>
)
})
}
function ViewFullThread({slice}: {slice: FeedPostSlice}) {
const pal = usePalette('default')

View file

@ -1,6 +1,5 @@
import * as React from 'react'
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {observer} from 'mobx-react-lite'
import {
AppBskyActorDefs,
moderateProfile,
@ -152,7 +151,7 @@ function ProfileCardPills({
)
}
const FollowersList = observer(function FollowersListImpl({
function FollowersList({
followers,
}: {
followers?: AppBskyActorDefs.ProfileView[] | undefined
@ -196,7 +195,7 @@ const FollowersList = observer(function FollowersListImpl({
))}
</View>
)
})
}
export function ProfileCardWithFollowBtn({
profile,

View file

@ -1,6 +1,5 @@
import React from 'react'
import {Pressable, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useNavigation} from '@react-navigation/native'
import {usePalette} from 'lib/hooks/usePalette'
@ -12,7 +11,6 @@ import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
import {CenteredView} from '../util/Views'
import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links'
import {useStores} from 'state/index'
import {NavigationProp} from 'lib/routes/types'
import {BACK_HITSLOP} from 'lib/constants'
import {isNative} from 'platform/detection'
@ -22,7 +20,7 @@ import {msg} from '@lingui/macro'
import {useSetDrawerOpen} from '#/state/shell'
import {emitSoftReset} from '#/state/events'
export const ProfileSubpageHeader = observer(function HeaderImpl({
export function ProfileSubpageHeader({
isLoading,
href,
title,
@ -45,7 +43,6 @@ export const ProfileSubpageHeader = observer(function HeaderImpl({
| undefined
avatarType: UserAvatarType
}>) {
const store = useStores()
const setDrawerOpen = useSetDrawerOpen()
const navigation = useNavigation<NavigationProp>()
const {_} = useLingui()
@ -183,7 +180,7 @@ export const ProfileSubpageHeader = observer(function HeaderImpl({
</View>
</CenteredView>
)
})
}
const styles = StyleSheet.create({
backBtn: {

View file

@ -6,7 +6,6 @@ import {niceDate} from 'lib/strings/time'
import {usePalette} from 'lib/hooks/usePalette'
import {TypographyVariant} from 'lib/ThemeContext'
import {UserAvatar} from './UserAvatar'
import {observer} from 'mobx-react-lite'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {sanitizeHandle} from 'lib/strings/handles'
import {isAndroid} from 'platform/detection'
@ -30,7 +29,7 @@ interface PostMetaOpts {
style?: StyleProp<ViewStyle>
}
export const PostMeta = observer(function PostMetaImpl(opts: PostMetaOpts) {
export function PostMeta(opts: PostMetaOpts) {
const pal = usePalette('default')
const displayName = opts.author.displayName || opts.author.handle
const handle = opts.author.handle
@ -92,7 +91,7 @@ export const PostMeta = observer(function PostMetaImpl(opts: PostMetaOpts) {
</TimeElapsed>
</View>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -1,5 +1,4 @@
import React from 'react'
import {observer} from 'mobx-react-lite'
import {
StyleProp,
StyleSheet,
@ -18,7 +17,7 @@ import {useSetDrawerOpen} from '#/state/shell'
const BACK_HITSLOP = {left: 20, top: 20, right: 50, bottom: 20}
export const SimpleViewHeader = observer(function SimpleViewHeaderImpl({
export function SimpleViewHeader({
showBackButton = true,
style,
children,
@ -76,7 +75,7 @@ export const SimpleViewHeader = observer(function SimpleViewHeaderImpl({
{children}
</Container>
)
})
}
const styles = StyleSheet.create({
header: {

View file

@ -1,5 +1,4 @@
import React from 'react'
import {observer} from 'mobx-react-lite'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useNavigation} from '@react-navigation/native'
@ -15,7 +14,7 @@ import {useSetDrawerOpen} from '#/state/shell'
const BACK_HITSLOP = {left: 20, top: 20, right: 50, bottom: 20}
export const ViewHeader = observer(function ViewHeaderImpl({
export function ViewHeader({
title,
canGoBack,
showBackButton = true,
@ -108,7 +107,7 @@ export const ViewHeader = observer(function ViewHeaderImpl({
</Container>
)
}
})
}
function DesktopWebHeader({
title,
@ -140,7 +139,7 @@ function DesktopWebHeader({
)
}
const Container = observer(function ContainerImpl({
function Container({
children,
hideOnScroll,
showBorder,
@ -178,7 +177,7 @@ const Container = observer(function ContainerImpl({
{children}
</Animated.View>
)
})
}
const styles = StyleSheet.create({
header: {

View file

@ -1,5 +1,4 @@
import React, {ComponentProps} from 'react'
import {observer} from 'mobx-react-lite'
import {StyleSheet, TouchableWithoutFeedback} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'
import {gradients} from 'lib/styles'
@ -15,11 +14,7 @@ export interface FABProps
icon: JSX.Element
}
export const FABInner = observer(function FABInnerImpl({
testID,
icon,
...props
}: FABProps) {
export function FABInner({testID, icon, ...props}: FABProps) {
const insets = useSafeAreaInsets()
const {isMobile, isTablet} = useWebMediaQueries()
const {fabMinimalShellTransform} = useMinimalShellMode()
@ -55,7 +50,7 @@ export const FABInner = observer(function FABInnerImpl({
</Animated.View>
</TouchableWithoutFeedback>
)
})
}
const styles = StyleSheet.create({
sizeRegular: {

View file

@ -2,8 +2,8 @@ import React from 'react'
import {StyleProp, StyleSheet, Pressable, View, ViewStyle} from 'react-native'
import {Image} from 'expo-image'
import {clamp} from 'lib/numbers'
import {useStores} from 'state/index'
import {Dimensions} from 'lib/media/types'
import * as imageSizes from 'lib/media/image-sizes'
const MIN_ASPECT_RATIO = 0.33 // 1/3
const MAX_ASPECT_RATIO = 5 // 5/1
@ -29,9 +29,8 @@ export function AutoSizedImage({
style,
children = null,
}: Props) {
const store = useStores()
const [dim, setDim] = React.useState<Dimensions | undefined>(
dimensionsHint || store.imageSizes.get(uri),
dimensionsHint || imageSizes.get(uri),
)
const [aspectRatio, setAspectRatio] = React.useState<number>(
dim ? calc(dim) : 1,
@ -41,14 +40,14 @@ export function AutoSizedImage({
if (dim) {
return
}
store.imageSizes.fetch(uri).then(newDim => {
imageSizes.fetch(uri).then(newDim => {
if (aborted) {
return
}
setDim(newDim)
setAspectRatio(calc(newDim))
})
}, [dim, setDim, setAspectRatio, store, uri])
}, [dim, setDim, setAspectRatio, uri])
if (onPress || onLongPress || onPressIn) {
return (

View file

@ -1,6 +1,5 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
@ -12,7 +11,7 @@ const AnimatedTouchableOpacity =
Animated.createAnimatedComponent(TouchableOpacity)
import {isWeb} from 'platform/detection'
export const LoadLatestBtn = observer(function LoadLatestBtnImpl({
export function LoadLatestBtn({
onPress,
label,
showIndicator,
@ -44,7 +43,7 @@ export const LoadLatestBtn = observer(function LoadLatestBtnImpl({
{showIndicator && <View style={[styles.indicator, pal.borderDark]} />}
</AnimatedTouchableOpacity>
)
})
}
const styles = StyleSheet.create({
loadLatest: {

View file

@ -1,12 +1,11 @@
import React from 'react'
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {usePalette} from 'lib/hooks/usePalette'
import {observer} from 'mobx-react-lite'
import {ListCard} from 'view/com/lists/ListCard'
import {AppBskyGraphDefs} from '@atproto/api'
import {s} from 'lib/styles'
export const ListEmbed = observer(function ListEmbedImpl({
export function ListEmbed({
item,
style,
}: {
@ -20,7 +19,7 @@ export const ListEmbed = observer(function ListEmbedImpl({
<ListCard list={item} style={[style, styles.card]} />
</View>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -1,6 +1,5 @@
import React from 'react'
import {useFocusEffect} from '@react-navigation/native'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
@ -15,130 +14,126 @@ import {usePreferencesQuery} from '#/state/queries/preferences'
import {emitSoftReset} from '#/state/events'
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
export const HomeScreen = withAuthRequired(
observer(function HomeScreenImpl({}: Props) {
const setMinimalShellMode = useSetMinimalShellMode()
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
const pagerRef = React.useRef<PagerRef>(null)
const [selectedPage, setSelectedPage] = React.useState(0)
const [customFeeds, setCustomFeeds] = React.useState<FeedDescriptor[]>([])
const {data: preferences} = usePreferencesQuery()
export const HomeScreen = withAuthRequired(function HomeScreenImpl({}: Props) {
const setMinimalShellMode = useSetMinimalShellMode()
const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
const pagerRef = React.useRef<PagerRef>(null)
const [selectedPage, setSelectedPage] = React.useState(0)
const [customFeeds, setCustomFeeds] = React.useState<FeedDescriptor[]>([])
const {data: preferences} = usePreferencesQuery()
React.useEffect(() => {
if (!preferences?.feeds?.pinned) return
React.useEffect(() => {
if (!preferences?.feeds?.pinned) return
const pinned = preferences.feeds.pinned
const pinned = preferences.feeds.pinned
const feeds: FeedDescriptor[] = []
const feeds: FeedDescriptor[] = []
for (const uri of pinned) {
if (uri.includes('app.bsky.feed.generator')) {
feeds.push(`feedgen|${uri}`)
} else if (uri.includes('app.bsky.graph.list')) {
feeds.push(`list|${uri}`)
}
for (const uri of pinned) {
if (uri.includes('app.bsky.feed.generator')) {
feeds.push(`feedgen|${uri}`)
} else if (uri.includes('app.bsky.graph.list')) {
feeds.push(`list|${uri}`)
}
}
setCustomFeeds(feeds)
setCustomFeeds(feeds)
pagerRef.current?.setPage(0)
}, [preferences?.feeds?.pinned, setCustomFeeds, pagerRef])
pagerRef.current?.setPage(0)
}, [preferences?.feeds?.pinned, setCustomFeeds, pagerRef])
const homeFeedParams = React.useMemo<FeedParams>(() => {
if (!preferences) return {}
const homeFeedParams = React.useMemo<FeedParams>(() => {
if (!preferences) return {}
return {
mergeFeedEnabled: Boolean(
preferences.feedViewPrefs.lab_mergeFeedEnabled,
),
mergeFeedSources: preferences.feeds.saved,
return {
mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled),
mergeFeedSources: preferences.feeds.saved,
}
}, [preferences])
useFocusEffect(
React.useCallback(() => {
setMinimalShellMode(false)
setDrawerSwipeDisabled(selectedPage > 0)
return () => {
setDrawerSwipeDisabled(false)
}
}, [preferences])
}, [setDrawerSwipeDisabled, selectedPage, setMinimalShellMode]),
)
useFocusEffect(
React.useCallback(() => {
const onPageSelected = React.useCallback(
(index: number) => {
setMinimalShellMode(false)
setSelectedPage(index)
setDrawerSwipeDisabled(index > 0)
},
[setDrawerSwipeDisabled, setSelectedPage, setMinimalShellMode],
)
const onPressSelected = React.useCallback(() => {
emitSoftReset()
}, [])
const onPageScrollStateChanged = React.useCallback(
(state: 'idle' | 'dragging' | 'settling') => {
if (state === 'dragging') {
setMinimalShellMode(false)
setDrawerSwipeDisabled(selectedPage > 0)
return () => {
setDrawerSwipeDisabled(false)
}
}, [setDrawerSwipeDisabled, selectedPage, setMinimalShellMode]),
)
}
},
[setMinimalShellMode],
)
const onPageSelected = React.useCallback(
(index: number) => {
setMinimalShellMode(false)
setSelectedPage(index)
setDrawerSwipeDisabled(index > 0)
},
[setDrawerSwipeDisabled, setSelectedPage, setMinimalShellMode],
)
const renderTabBar = React.useCallback(
(props: RenderTabBarFnProps) => {
return (
<FeedsTabBar
key="FEEDS_TAB_BAR"
selectedPage={props.selectedPage}
onSelect={props.onSelect}
testID="homeScreenFeedTabs"
onPressSelected={onPressSelected}
/>
)
},
[onPressSelected],
)
const onPressSelected = React.useCallback(() => {
emitSoftReset()
}, [])
const renderFollowingEmptyState = React.useCallback(() => {
return <FollowingEmptyState />
}, [])
const onPageScrollStateChanged = React.useCallback(
(state: 'idle' | 'dragging' | 'settling') => {
if (state === 'dragging') {
setMinimalShellMode(false)
}
},
[setMinimalShellMode],
)
const renderCustomFeedEmptyState = React.useCallback(() => {
return <CustomFeedEmptyState />
}, [])
const renderTabBar = React.useCallback(
(props: RenderTabBarFnProps) => {
return (
<Pager
ref={pagerRef}
testID="homeScreen"
onPageSelected={onPageSelected}
onPageScrollStateChanged={onPageScrollStateChanged}
renderTabBar={renderTabBar}
tabBarPosition="top">
<FeedPage
key="1"
testID="followingFeedPage"
isPageFocused={selectedPage === 0}
feed="home"
feedParams={homeFeedParams}
renderEmptyState={renderFollowingEmptyState}
renderEndOfFeed={FollowingEndOfFeed}
/>
{customFeeds.map((f, index) => {
return (
<FeedsTabBar
key="FEEDS_TAB_BAR"
selectedPage={props.selectedPage}
onSelect={props.onSelect}
testID="homeScreenFeedTabs"
onPressSelected={onPressSelected}
<FeedPage
key={f}
testID="customFeedPage"
isPageFocused={selectedPage === 1 + index}
feed={f}
renderEmptyState={renderCustomFeedEmptyState}
/>
)
},
[onPressSelected],
)
const renderFollowingEmptyState = React.useCallback(() => {
return <FollowingEmptyState />
}, [])
const renderCustomFeedEmptyState = React.useCallback(() => {
return <CustomFeedEmptyState />
}, [])
return (
<Pager
ref={pagerRef}
testID="homeScreen"
onPageSelected={onPageSelected}
onPageScrollStateChanged={onPageScrollStateChanged}
renderTabBar={renderTabBar}
tabBarPosition="top">
<FeedPage
key="1"
testID="followingFeedPage"
isPageFocused={selectedPage === 0}
feed="home"
feedParams={homeFeedParams}
renderEmptyState={renderFollowingEmptyState}
renderEndOfFeed={FollowingEndOfFeed}
/>
{customFeeds.map((f, index) => {
return (
<FeedPage
key={f}
testID="customFeedPage"
isPageFocused={selectedPage === 1 + index}
feed={f}
renderEmptyState={renderCustomFeedEmptyState}
/>
)
})}
</Pager>
)
}),
)
})}
</Pager>
)
})

View file

@ -1,6 +1,5 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {Text} from '../com/util/text/Text'
import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
@ -23,9 +22,7 @@ import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'LanguageSettings'>
export const LanguageSettingsScreen = observer(function LanguageSettingsImpl(
_: Props,
) {
export function LanguageSettingsScreen(_: Props) {
const pal = usePalette('default')
const langPrefs = useLanguagePrefs()
const setLangPrefs = useLanguagePrefsApi()
@ -192,7 +189,7 @@ export const LanguageSettingsScreen = observer(function LanguageSettingsImpl(
</View>
</CenteredView>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -1,7 +1,6 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {useFocusEffect} from '@react-navigation/native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
import {ScrollView} from '../com/util/Views'
@ -15,7 +14,7 @@ import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
import {useSetMinimalShellMode} from '#/state/shell'
export const LogScreen = observer(function Log({}: NativeStackScreenProps<
export function LogScreen({}: NativeStackScreenProps<
CommonNavigatorParams,
'Log'
>) {
@ -88,7 +87,7 @@ export const LogScreen = observer(function Log({}: NativeStackScreenProps<
</ScrollView>
</View>
)
})
}
const styles = StyleSheet.create({
entry: {

View file

@ -5,7 +5,6 @@ import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {s} from 'lib/styles'
@ -21,7 +20,7 @@ import {useModalControls} from '#/state/modals'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Moderation'>
export const ModerationScreen = withAuthRequired(
observer(function Moderation({}: Props) {
function Moderation({}: Props) {
const pal = usePalette('default')
const setMinimalShellMode = useSetMinimalShellMode()
const {screen, track} = useAnalytics()
@ -111,7 +110,7 @@ export const ModerationScreen = withAuthRequired(
</Link>
</CenteredView>
)
}),
},
)
const styles = StyleSheet.create({

View file

@ -3,7 +3,6 @@ import {StyleSheet, View} from 'react-native'
import Animated from 'react-native-reanimated'
import {useFocusEffect} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
import {makeRecordUri} from 'lib/strings/url-helpers'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
@ -26,83 +25,83 @@ import {CenteredView} from '../com/util/Views'
import {useComposerControls} from '#/state/shell/composer'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>
export const PostThreadScreen = withAuthRequired(
observer(function PostThreadScreenImpl({route}: Props) {
const queryClient = useQueryClient()
const {fabMinimalShellTransform} = useMinimalShellMode()
const setMinimalShellMode = useSetMinimalShellMode()
const {openComposer} = useComposerControls()
const safeAreaInsets = useSafeAreaInsets()
const {name, rkey} = route.params
const {isMobile} = useWebMediaQueries()
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
const {data: resolvedUri, error: uriError} = useResolveUriQuery(uri)
export const PostThreadScreen = withAuthRequired(function PostThreadScreenImpl({
route,
}: Props) {
const queryClient = useQueryClient()
const {fabMinimalShellTransform} = useMinimalShellMode()
const setMinimalShellMode = useSetMinimalShellMode()
const {openComposer} = useComposerControls()
const safeAreaInsets = useSafeAreaInsets()
const {name, rkey} = route.params
const {isMobile} = useWebMediaQueries()
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
const {data: resolvedUri, error: uriError} = useResolveUriQuery(uri)
useFocusEffect(
React.useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
useFocusEffect(
React.useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
const onPressReply = React.useCallback(() => {
if (!resolvedUri) {
return
}
const thread = queryClient.getQueryData<ThreadNode>(
POST_THREAD_RQKEY(resolvedUri.uri),
)
const onPressReply = React.useCallback(() => {
if (!resolvedUri) {
return
}
const thread = queryClient.getQueryData<ThreadNode>(
POST_THREAD_RQKEY(resolvedUri.uri),
)
if (thread?.type !== 'post') {
return
}
openComposer({
replyTo: {
uri: thread.post.uri,
cid: thread.post.cid,
text: thread.record.text,
author: {
handle: thread.post.author.handle,
displayName: thread.post.author.displayName,
avatar: thread.post.author.avatar,
},
if (thread?.type !== 'post') {
return
}
openComposer({
replyTo: {
uri: thread.post.uri,
cid: thread.post.cid,
text: thread.record.text,
author: {
handle: thread.post.author.handle,
displayName: thread.post.author.displayName,
avatar: thread.post.author.avatar,
},
onPost: () =>
queryClient.invalidateQueries({
queryKey: POST_THREAD_RQKEY(resolvedUri.uri || ''),
}),
})
}, [openComposer, queryClient, resolvedUri])
},
onPost: () =>
queryClient.invalidateQueries({
queryKey: POST_THREAD_RQKEY(resolvedUri.uri || ''),
}),
})
}, [openComposer, queryClient, resolvedUri])
return (
<View style={s.hContentRegion}>
{isMobile && <ViewHeader title="Post" />}
<View style={s.flex1}>
{uriError ? (
<CenteredView>
<ErrorMessage message={String(uriError)} />
</CenteredView>
) : (
<PostThreadComponent
uri={resolvedUri?.uri}
onPressReply={onPressReply}
/>
)}
</View>
{isMobile && (
<Animated.View
style={[
styles.prompt,
fabMinimalShellTransform,
{
bottom: clamp(safeAreaInsets.bottom, 15, 30),
},
]}>
<ComposePrompt onPressCompose={onPressReply} />
</Animated.View>
return (
<View style={s.hContentRegion}>
{isMobile && <ViewHeader title="Post" />}
<View style={s.flex1}>
{uriError ? (
<CenteredView>
<ErrorMessage message={String(uriError)} />
</CenteredView>
) : (
<PostThreadComponent
uri={resolvedUri?.uri}
onPressReply={onPressReply}
/>
)}
</View>
)
}),
)
{isMobile && (
<Animated.View
style={[
styles.prompt,
fabMinimalShellTransform,
{
bottom: clamp(safeAreaInsets.bottom, 15, 30),
},
]}>
<ComposePrompt onPressCompose={onPressReply} />
</Animated.View>
)}
</View>
)
})
const styles = StyleSheet.create({
prompt: {

View file

@ -1,6 +1,5 @@
import React, {useState} from 'react'
import {ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Slider} from '@miblanchard/react-native-slider'
import {Text} from '../com/util/text/Text'
@ -72,9 +71,7 @@ type Props = NativeStackScreenProps<
CommonNavigatorParams,
'PreferencesHomeFeed'
>
export const PreferencesHomeFeed = observer(function PreferencesHomeFeedImpl({
navigation,
}: Props) {
export function PreferencesHomeFeed({navigation}: Props) {
const pal = usePalette('default')
const {_} = useLingui()
const {isTabletOrDesktop} = useWebMediaQueries()
@ -308,7 +305,7 @@ export const PreferencesHomeFeed = observer(function PreferencesHomeFeedImpl({
</View>
</CenteredView>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -6,7 +6,6 @@ import {
TouchableOpacity,
View,
} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Text} from '../com/util/text/Text'
import {s, colors} from 'lib/styles'
@ -25,9 +24,7 @@ import {
} from '#/state/queries/preferences'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PreferencesThreads'>
export const PreferencesThreads = observer(function PreferencesThreadsImpl({
navigation,
}: Props) {
export function PreferencesThreads({navigation}: Props) {
const pal = usePalette('default')
const {_} = useLingui()
const {isTabletOrDesktop} = useWebMediaQueries()
@ -162,7 +159,7 @@ export const PreferencesThreads = observer(function PreferencesThreadsImpl({
</View>
</CenteredView>
)
})
}
const styles = StyleSheet.create({
container: {

View file

@ -15,7 +15,6 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {CommonNavigatorParams} from 'lib/routes/types'
import {makeRecordUri} from 'lib/strings/url-helpers'
import {colors, s} from 'lib/styles'
import {observer} from 'mobx-react-lite'
import {FeedDescriptor} from '#/state/queries/post-feed'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
@ -71,7 +70,7 @@ interface SectionRef {
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFeed'>
export const ProfileFeedScreen = withAuthRequired(
observer(function ProfileFeedScreenImpl(props: Props) {
function ProfileFeedScreenImpl(props: Props) {
const {rkey, name: handleOrDid} = props.route.params
const pal = usePalette('default')
@ -129,7 +128,7 @@ export const ProfileFeedScreen = withAuthRequired(
</View>
</CenteredView>
)
}),
},
)
function ProfileFeedScreenIntermediate({feedUri}: {feedUri: string}) {
@ -154,7 +153,7 @@ function ProfileFeedScreenIntermediate({feedUri}: {feedUri: string}) {
)
}
export const ProfileFeedScreenInner = function ProfileFeedScreenInnerImpl({
export function ProfileFeedScreenInner({
preferences,
feedInfo,
}: {
@ -485,7 +484,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
},
)
const AboutSection = observer(function AboutPageImpl({
function AboutSection({
feedOwnerDid,
feedRkey,
feedInfo,
@ -606,7 +605,7 @@ const AboutSection = observer(function AboutPageImpl({
</View>
</ScrollView>
)
})
}
const styles = StyleSheet.create({
btn: {

View file

@ -14,7 +14,6 @@ import {track} from '#/lib/analytics/analytics'
import {useAnalytics} from 'lib/analytics/analytics'
import {usePalette} from 'lib/hooks/usePalette'
import {CommonNavigatorParams} from 'lib/routes/types'
import {observer} from 'mobx-react-lite'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {ViewHeader} from 'view/com/util/ViewHeader'
@ -146,7 +145,7 @@ export const SavedFeeds = withAuthRequired(function SavedFeedsImpl({}: Props) {
)
})
const ListItem = observer(function ListItemImpl({
function ListItem({
feedUri,
isPinned,
}: {
@ -269,7 +268,7 @@ const ListItem = observer(function ListItemImpl({
</TouchableOpacity>
</Pressable>
)
})
}
const styles = StyleSheet.create({
desktopContainer: {

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,6 @@ import {
ViewStyle,
} from 'react-native'
import {useNavigation, StackActions} from '@react-navigation/native'
import {observer} from 'mobx-react-lite'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
@ -101,7 +100,7 @@ export function DrawerProfileCard({
)
}
export const DrawerContent = observer(function DrawerContentImpl() {
export function DrawerContent() {
const theme = useTheme()
const pal = usePalette('default')
const {_} = useLingui()
@ -404,7 +403,7 @@ export const DrawerContent = observer(function DrawerContentImpl() {
</SafeAreaView>
</View>
)
})
}
interface MenuItemProps extends ComponentProps<typeof TouchableOpacity> {
icon: JSX.Element
@ -458,11 +457,7 @@ function MenuItem({
)
}
const InviteCodes = observer(function InviteCodesImpl({
style,
}: {
style?: StyleProp<ViewStyle>
}) {
function InviteCodes({style}: {style?: StyleProp<ViewStyle>}) {
const {track} = useAnalytics()
const setDrawerOpen = useSetDrawerOpen()
const pal = usePalette('default')
@ -502,7 +497,7 @@ const InviteCodes = observer(function InviteCodesImpl({
</Text>
</TouchableOpacity>
)
})
}
const styles = StyleSheet.create({
view: {

View file

@ -4,7 +4,6 @@ import Animated from 'react-native-reanimated'
import {StackActions} from '@react-navigation/native'
import {BottomTabBarProps} from '@react-navigation/bottom-tabs'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {observer} from 'mobx-react-lite'
import {Text} from 'view/com/util/text/Text'
import {useAnalytics} from 'lib/analytics/analytics'
import {clamp} from 'lib/numbers'
@ -34,9 +33,7 @@ import {useProfileQuery} from '#/state/queries/profile'
type TabOptions = 'Home' | 'Search' | 'Notifications' | 'MyProfile' | 'Feeds'
export const BottomBar = observer(function BottomBarImpl({
navigation,
}: BottomTabBarProps) {
export function BottomBar({navigation}: BottomTabBarProps) {
const {openModal} = useModalControls()
const {currentAccount} = useSession()
const pal = usePalette('default')
@ -231,7 +228,7 @@ export const BottomBar = observer(function BottomBarImpl({
/>
</Animated.View>
)
})
}
interface BtnProps
extends Pick<

View file

@ -1,5 +1,4 @@
import React from 'react'
import {observer} from 'mobx-react-lite'
import {usePalette} from 'lib/hooks/usePalette'
import {useNavigationState} from '@react-navigation/native'
import Animated from 'react-native-reanimated'
@ -24,7 +23,7 @@ import {makeProfileLink} from 'lib/routes/links'
import {CommonNavigatorParams} from 'lib/routes/types'
import {useSession} from '#/state/session'
export const BottomBarWeb = observer(function BottomBarWebImpl() {
export function BottomBarWeb() {
const {currentAccount} = useSession()
const pal = usePalette('default')
const safeAreaInsets = useSafeAreaInsets()
@ -111,7 +110,7 @@ export const BottomBarWeb = observer(function BottomBarWebImpl() {
</NavItem>
</Animated.View>
)
})
}
const NavItem: React.FC<{
children: (props: {isActive: boolean}) => React.ReactChild

View file

@ -1,13 +1,12 @@
import React from 'react'
import {View, StyleSheet} from 'react-native'
import {useNavigationState} from '@react-navigation/native'
import {observer} from 'mobx-react-lite'
import {usePalette} from 'lib/hooks/usePalette'
import {TextLink} from 'view/com/util/Link'
import {getCurrentRoute} from 'lib/routes/helpers'
import {usePinnedFeedsInfos} from '#/state/queries/feed'
export const DesktopFeeds = observer(function DesktopFeeds() {
export function DesktopFeeds() {
const pal = usePalette('default')
const feeds = usePinnedFeedsInfos()
@ -54,7 +53,7 @@ export const DesktopFeeds = observer(function DesktopFeeds() {
</View>
</View>
)
})
}
function FeedItem({
title,

View file

@ -1,5 +1,4 @@
import React from 'react'
import {observer} from 'mobx-react-lite'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {PressableWithHover} from 'view/com/util/PressableWithHover'
import {
@ -47,7 +46,7 @@ import {useComposerControls} from '#/state/shell/composer'
import {useFetchHandle} from '#/state/queries/handle'
import {emitSoftReset} from '#/state/events'
const ProfileCard = observer(function ProfileCardImpl() {
function ProfileCard() {
const {currentAccount} = useSession()
const {isLoading, data: profile} = useProfileQuery({did: currentAccount!.did})
const {isDesktop} = useWebMediaQueries()
@ -73,7 +72,7 @@ const ProfileCard = observer(function ProfileCardImpl() {
/>
</View>
)
})
}
function BackBtn() {
const {isTablet} = useWebMediaQueries()
@ -117,13 +116,7 @@ interface NavItemProps {
iconFilled: JSX.Element
label: string
}
const NavItem = observer(function NavItemImpl({
count,
href,
icon,
iconFilled,
label,
}: NavItemProps) {
function NavItem({count, href, icon, iconFilled, label}: NavItemProps) {
const pal = usePalette('default')
const {currentAccount} = useSession()
const {isDesktop, isTablet} = useWebMediaQueries()
@ -192,7 +185,7 @@ const NavItem = observer(function NavItemImpl({
)}
</PressableWithHover>
)
})
}
function ComposeBtn() {
const {currentAccount} = useSession()
@ -264,7 +257,7 @@ function ComposeBtn() {
)
}
export const DesktopLeftNav = observer(function DesktopLeftNav() {
export function DesktopLeftNav() {
const {currentAccount} = useSession()
const pal = usePalette('default')
const {isDesktop, isTablet} = useWebMediaQueries()
@ -422,7 +415,7 @@ export const DesktopLeftNav = observer(function DesktopLeftNav() {
<ComposeBtn />
</View>
)
})
}
const styles = StyleSheet.create({
leftNav: {

View file

@ -1,5 +1,4 @@
import React from 'react'
import {observer} from 'mobx-react-lite'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {usePalette} from 'lib/hooks/usePalette'
@ -16,7 +15,7 @@ import {useModalControls} from '#/state/modals'
import {useSession} from '#/state/session'
import {useInviteCodesQuery} from '#/state/queries/invites'
export const DesktopRightNav = observer(function DesktopRightNavImpl() {
export function DesktopRightNav() {
const pal = usePalette('default')
const palError = usePalette('error')
const {isSandbox, hasSession, currentAccount} = useSession()
@ -80,9 +79,9 @@ export const DesktopRightNav = observer(function DesktopRightNavImpl() {
<InviteCodes />
</View>
)
})
}
const InviteCodes = observer(function InviteCodesImpl() {
function InviteCodes() {
const pal = usePalette('default')
const {openModal} = useModalControls()
const {data: invites} = useInviteCodesQuery()
@ -118,7 +117,7 @@ const InviteCodes = observer(function InviteCodesImpl() {
</Text>
</TouchableOpacity>
)
})
}
const styles = StyleSheet.create({
rightNav: {

View file

@ -1,5 +1,4 @@
import React, {useEffect} from 'react'
import {observer} from 'mobx-react-lite'
import {View, StyleSheet, TouchableOpacity} from 'react-native'
import {DesktopLeftNav} from './desktop/LeftNav'
import {DesktopRightNav} from './desktop/RightNav'
@ -76,7 +75,7 @@ function ShellInner() {
)
}
export const Shell: React.FC = observer(function ShellImpl() {
export const Shell: React.FC = function ShellImpl() {
const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
return (
<View style={[s.hContentRegion, pageBg]}>
@ -85,7 +84,7 @@ export const Shell: React.FC = observer(function ShellImpl() {
</RoutesContainer>
</View>
)
})
}
const styles = StyleSheet.create({
bgLight: {