diff --git a/src/App.native.tsx b/src/App.native.tsx
index 0c146dcc9f..e1397dc970 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -1,239 +1,119 @@
-import 'react-native-url-polyfill/auto'
-import '#/lib/sentry' // must be near top
-import '#/lib/bitdrift' // must be near top
-import '#/view/icons'
-
-import React, {useEffect, useState} from 'react'
-import {GestureHandlerRootView} from 'react-native-gesture-handler'
-import {RootSiblingParent} from 'react-native-root-siblings'
+import {useState} from 'react'
+import {ScrollView, Text, View} from 'react-native'
import {
- initialWindowMetrics,
- SafeAreaProvider,
-} from 'react-native-safe-area-context'
-import * as ScreenOrientation from 'expo-screen-orientation'
-import * as SplashScreen from 'expo-splash-screen'
-import * as SystemUI from 'expo-system-ui'
-import {msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+ Gesture,
+ GestureDetector,
+ GestureHandlerRootView,
+} from 'react-native-gesture-handler'
+import PagerView from 'react-native-pager-view'
+import Animated, {
+ useAnimatedStyle,
+ useSharedValue,
+} from 'react-native-reanimated'
-import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController'
-import {QueryProvider} from '#/lib/react-query'
-import {Provider as StatsigProvider, tryFetchGates} from '#/lib/statsig/statsig'
-import {s} from '#/lib/styles'
-import {ThemeProvider} from '#/lib/ThemeContext'
-import I18nProvider from '#/locale/i18nProvider'
-import {logger} from '#/logger'
-import {isAndroid, isIOS} from '#/platform/detection'
-import {Provider as A11yProvider} from '#/state/a11y'
-import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
-import {Provider as DialogStateProvider} from '#/state/dialogs'
-import {listenSessionDropped} from '#/state/events'
-import {
- beginResolveGeolocation,
- ensureGeolocationResolved,
- Provider as GeolocationProvider,
-} from '#/state/geolocation'
-import {Provider as HomeBadgeProvider} from '#/state/home-badge'
-import {Provider as InvitesStateProvider} from '#/state/invites'
-import {Provider as LightboxStateProvider} from '#/state/lightbox'
-import {MessagesProvider} from '#/state/messages'
-import {Provider as ModalStateProvider} from '#/state/modals'
-import {init as initPersistedState} from '#/state/persisted'
-import {Provider as PrefsStateProvider} from '#/state/preferences'
-import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
-import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
-import {Provider as UnreadNotifsProvider} from '#/state/queries/notifications/unread'
-import {
- Provider as SessionProvider,
- SessionAccount,
- useSession,
- useSessionApi,
-} from '#/state/session'
-import {readLastActiveAccount} from '#/state/session/util'
-import {Provider as ShellStateProvider} from '#/state/shell'
-import {Provider as ComposerProvider} from '#/state/shell/composer'
-import {Provider as LightStatusBarProvider} from '#/state/shell/light-status-bar'
-import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out'
-import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide'
-import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed'
-import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
-import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies'
-import {Provider as TrendingConfigProvider} from '#/state/trending-config'
-import {TestCtrls} from '#/view/com/testing/TestCtrls'
-import {Provider as VideoVolumeProvider} from '#/view/com/util/post-embeds/VideoVolumeContext'
-import * as Toast from '#/view/com/util/Toast'
-import {Shell} from '#/view/shell'
-import {ThemeProvider as Alf} from '#/alf'
-import {useColorModeTheme} from '#/alf/util/useColorModeTheme'
-import {NuxDialogs} from '#/components/dialogs/nuxs'
-import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry'
-import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs'
-import {Provider as PortalProvider} from '#/components/Portal'
-import {Splash} from '#/Splash'
-import {BottomSheetProvider} from '../modules/bottom-sheet'
-import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
+export default function App() {
+ const val = useSharedValue(0)
+ const [swipeEnabled, setSwipeEnabled] = useState(true)
-SplashScreen.preventAutoHideAsync()
-if (isIOS) {
- SystemUI.setBackgroundColorAsync('black')
-}
-if (isAndroid) {
- // iOS is handled by the config plugin -sfn
- ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP)
-}
-
-/**
- * Begin geolocation ASAP
- */
-beginResolveGeolocation()
-
-function InnerApp() {
- const [isReady, setIsReady] = React.useState(false)
- const {currentAccount} = useSession()
- const {resumeSession} = useSessionApi()
- const theme = useColorModeTheme()
- const {_} = useLingui()
-
- const hasCheckedReferrer = useStarterPackEntry()
-
- // init
- useEffect(() => {
- async function onLaunch(account?: SessionAccount) {
- try {
- if (account) {
- await resumeSession(account)
- } else {
- await tryFetchGates(undefined, 'prefer-fresh-gates')
- }
- } catch (e) {
- logger.error(`session: resume failed`, {message: e})
- } finally {
- setIsReady(true)
- }
- }
- const account = readLastActiveAccount()
- onLaunch(account)
- }, [resumeSession])
-
- useEffect(() => {
- return listenSessionDropped(() => {
- Toast.show(
- _(msg`Sorry! Your session expired. Please log in again.`),
- 'info',
- )
+ let pan = Gesture.Pan()
+ .onBegin(() => {
+ 'worklet'
+ console.log('begin')
+ val.set(0)
+ })
+ .onUpdate(e => {
+ 'worklet'
+ console.log('update')
+ val.set(e.translationX)
+ })
+ .onEnd(() => {
+ 'worklet'
+ console.log('end')
+ val.set(0)
+ })
+ .onFinalize(() => {
+ 'worklet'
+ console.log('finalize')
+ val.set(0)
})
- }, [_])
- return (
-
-
-
-
-
-
-
-
-
-
- {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
-
-function App() {
- const [isReady, setReady] = useState(false)
-
- React.useEffect(() => {
- Promise.all([initPersistedState(), ensureGeolocationResolved()]).then(() =>
- setReady(true),
- )
- }, [])
-
- if (!isReady) {
- return null
+ if (swipeEnabled) {
+ pan = pan.failOffsetX(-1).activeOffsetX(5)
+ } else {
+ pan = pan.failOffsetX([0, 0]).failOffsetY([0, 0])
}
- /*
- * NOTE: only nothing here can depend on other data or session state, since
- * that is set up in the InnerApp component above.
- */
+ const style = useAnimatedStyle(() => {
+ return {
+ flex: 1,
+ transform: [
+ {
+ translateX: val.value,
+ },
+ ],
+ }
+ })
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
)
}
-export default App
+function Pager({children, pan, setSwipeEnabled}) {
+ const native = Gesture.Native().requireExternalGestureToFail(pan)
+ return (
+
+ {
+ setSwipeEnabled(e.nativeEvent.position === 0)
+ }}>
+ {children}
+ {children}
+ {children}
+
+
+ )
+}
+
+function InnerScrollView({pan}) {
+ const native = Gesture.Native().blocksExternalGesture(pan)
+ return (
+
+
+
+
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
+ 27 28 29 30 31 32 33 34 35 36 37 38 39 40
+
+
+
+
+ )
+}