diff --git a/src/App.native.tsx b/src/App.native.tsx
index e0e030cb..f4f787a0 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -13,6 +13,7 @@ import {RootStoreModel, setupState, RootStoreProvider} from './state'
import {Shell} from './view/shell'
import * as notifee from 'lib/notifee'
import * as analytics from 'lib/analytics'
+import * as backHandler from 'lib/routes/back-handler'
import * as Toast from './view/com/util/Toast'
import {handleLink} from './Navigation'
@@ -28,6 +29,7 @@ const App = observer(() => {
setRootStore(store)
analytics.init(store)
notifee.init(store)
+ backHandler.init(store)
SplashScreen.hideAsync()
Linking.getInitialURL().then((url: string | null) => {
if (url) {
diff --git a/src/lib/routes/back-handler.ts b/src/lib/routes/back-handler.ts
new file mode 100644
index 00000000..feb92845
--- /dev/null
+++ b/src/lib/routes/back-handler.ts
@@ -0,0 +1,11 @@
+import {BackHandler} from 'react-native'
+import {RootStoreModel} from 'state/index'
+
+export function onBack(cb: () => boolean): () => void {
+ const subscription = BackHandler.addEventListener('hardwareBackPress', cb)
+ return () => subscription.remove()
+}
+
+export function init(store: RootStoreModel) {
+ onBack(() => store.shell.closeAnyActiveElement())
+}
diff --git a/src/state/models/ui/shell.ts b/src/state/models/ui/shell.ts
index 6c58262d..a2891d9b 100644
--- a/src/state/models/ui/shell.ts
+++ b/src/state/models/ui/shell.ts
@@ -194,6 +194,30 @@ export class ShellUiModel {
this.minimalShellMode = v
}
+ /**
+ * returns true if something was closed
+ * (used by the android hardware back btn)
+ */
+ closeAnyActiveElement(): boolean {
+ if (this.isLightboxActive) {
+ this.closeLightbox()
+ return true
+ }
+ if (this.isModalActive) {
+ this.closeModal()
+ return true
+ }
+ if (this.isComposerActive) {
+ this.closeComposer()
+ return true
+ }
+ if (this.isDrawerOpen) {
+ this.closeDrawer()
+ return true
+ }
+ return false
+ }
+
openDrawer() {
this.isDrawerOpen = true
}
diff --git a/src/view/com/lightbox/Lightbox.tsx b/src/view/com/lightbox/Lightbox.tsx
index d6cc8c25..06b48143 100644
--- a/src/view/com/lightbox/Lightbox.tsx
+++ b/src/view/com/lightbox/Lightbox.tsx
@@ -1,5 +1,4 @@
import React from 'react'
-import {View} from 'react-native'
import {observer} from 'mobx-react-lite'
import ImageView from './ImageViewing'
import {useStores} from 'state/index'
@@ -48,6 +47,6 @@ export const Lightbox = observer(function Lightbox() {
/>
)
} else {
- return
+ return null
}
})
diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx
index 0feae3a8..5a1ba363 100644
--- a/src/view/com/modals/EditProfile.tsx
+++ b/src/view/com/modals/EditProfile.tsx
@@ -1,13 +1,15 @@
-import React, {useState} from 'react'
+import React, {useState, useCallback} from 'react'
import * as Toast from '../util/Toast'
import {
ActivityIndicator,
+ KeyboardAvoidingView,
+ ScrollView,
StyleSheet,
+ TextInput,
TouchableOpacity,
View,
} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'
-import {ScrollView, TextInput} from './util'
import {Image as RNImage} from 'react-native-image-crop-picker'
import {Text} from '../util/text/Text'
import {ErrorMessage} from '../util/error/ErrorMessage'
@@ -24,7 +26,7 @@ import {useTheme} from 'lib/ThemeContext'
import {useAnalytics} from 'lib/analytics'
import {cleanError, isNetworkError} from 'lib/strings/errors'
-export const snapPoints = ['80%']
+export const snapPoints = ['fullscreen']
export function Component({
profileView,
@@ -61,38 +63,43 @@ export function Component({
const onPressCancel = () => {
store.shell.closeModal()
}
- const onSelectNewAvatar = async (img: RNImage | null) => {
- track('EditProfile:AvatarSelected')
- try {
- // if img is null, user selected "remove avatar"
+ const onSelectNewAvatar = useCallback(
+ async (img: RNImage | null) => {
if (!img) {
setNewUserAvatar(null)
setUserAvatar(null)
return
}
- const finalImg = await compressIfNeeded(img, 1000000)
- setNewUserAvatar(finalImg)
- setUserAvatar(finalImg.path)
- } catch (e: any) {
- setError(cleanError(e))
- }
- }
- const onSelectNewBanner = async (img: RNImage | null) => {
- if (!img) {
- setNewUserBanner(null)
- setUserBanner(null)
- return
- }
- track('EditProfile:BannerSelected')
- try {
- const finalImg = await compressIfNeeded(img, 1000000)
- setNewUserBanner(finalImg)
- setUserBanner(finalImg.path)
- } catch (e: any) {
- setError(cleanError(e))
- }
- }
- const onPressSave = async () => {
+ track('EditProfile:AvatarSelected')
+ try {
+ const finalImg = await compressIfNeeded(img, 1000000)
+ setNewUserAvatar(finalImg)
+ setUserAvatar(finalImg.path)
+ } catch (e: any) {
+ setError(cleanError(e))
+ }
+ },
+ [track, setNewUserAvatar, setUserAvatar, setError],
+ )
+ const onSelectNewBanner = useCallback(
+ async (img: RNImage | null) => {
+ if (!img) {
+ setNewUserBanner(null)
+ setUserBanner(null)
+ return
+ }
+ track('EditProfile:BannerSelected')
+ try {
+ const finalImg = await compressIfNeeded(img, 1000000)
+ setNewUserBanner(finalImg)
+ setUserBanner(finalImg.path)
+ } catch (e: any) {
+ setError(cleanError(e))
+ }
+ },
+ [track, setNewUserBanner, setUserBanner, setError],
+ )
+ const onPressSave = useCallback(async () => {
track('EditProfile:Save')
setProcessing(true)
if (error) {
@@ -120,11 +127,23 @@ export function Component({
}
}
setProcessing(false)
- }
+ }, [
+ track,
+ setProcessing,
+ setError,
+ error,
+ profileView,
+ onUpdate,
+ store,
+ displayName,
+ description,
+ newUserAvatar,
+ newUserBanner,
+ ])
return (
-
-
+
+
Edit my profile
)}
-
- Display Name
- setDisplayName(enforceLen(v, MAX_DISPLAY_NAME))}
- />
-
-
- Description
- setDescription(enforceLen(v, MAX_DESCRIPTION))}
- />
-
- {isProcessing ? (
-
-
+
+
+ Display Name
+
+ setDisplayName(enforceLen(v, MAX_DISPLAY_NAME))
+ }
+ />
- ) : (
+
+ Description
+ setDescription(enforceLen(v, MAX_DESCRIPTION))}
+ />
+
+ {isProcessing ? (
+
+
+
+ ) : (
+
+
+ Save Changes
+
+
+ )}
-
- Save Changes
-
+ testID="editProfileCancelBtn"
+ style={s.mt5}
+ onPress={onPressCancel}>
+
+ Cancel
+
- )}
-
-
- Cancel
-
-
+
-
+
)
}
const styles = StyleSheet.create({
- inner: {
- padding: 14,
- },
title: {
textAlign: 'center',
fontWeight: 'bold',
@@ -215,6 +235,9 @@ const styles = StyleSheet.create({
paddingBottom: 4,
marginTop: 20,
},
+ form: {
+ paddingHorizontal: 14,
+ },
textInput: {
borderWidth: 1,
borderRadius: 6,
@@ -243,7 +266,7 @@ const styles = StyleSheet.create({
avi: {
position: 'absolute',
top: 80,
- left: 10,
+ left: 24,
width: 84,
height: 84,
borderWidth: 2,
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx
index 5d034a19..df7d7f04 100644
--- a/src/view/com/modals/Modal.tsx
+++ b/src/view/com/modals/Modal.tsx
@@ -1,5 +1,6 @@
import React, {useRef, useEffect} from 'react'
import {StyleSheet} from 'react-native'
+import {SafeAreaView} from 'react-native-safe-area-context'
import {observer} from 'mobx-react-lite'
import BottomSheet from '@gorhom/bottom-sheet'
import {useStores} from 'state/index'
@@ -92,13 +93,22 @@ export const ModalsContainer = observer(function ModalsContainer() {
return null
}
+ if (snapPoints[0] === 'fullscreen') {
+ return (
+
+ {element}
+
+ )
+ }
+
return (
void
}) {
const [selectedIndex, setSelectedIndex] = useState(0)
- const panX = useAnimatedValue(0)
// events
// =
- const onSwipeEnd = React.useCallback(
- (dx: number) => {
- if (dx !== 0) {
- setSelectedIndex(clamp(selectedIndex + dx, 0, sections.length))
- }
- },
- [setSelectedIndex, selectedIndex, sections],
- )
+ const keyExtractor = React.useCallback(item => item._reactKey, [])
+
const onPressSelection = React.useCallback(
(index: number) => setSelectedIndex(clamp(index, 0, sections.length)),
[setSelectedIndex, sections],
@@ -77,7 +70,6 @@ export function ViewSelector({
return (
@@ -86,7 +78,7 @@ export function ViewSelector({
return renderItem(item)
}
},
- [sections, panX, selectedIndex, onPressSelection, renderHeader, renderItem],
+ [sections, selectedIndex, onPressSelection, renderHeader, renderItem],
)
const data = React.useMemo(
@@ -94,28 +86,98 @@ export function ViewSelector({
[items],
)
return (
- 0}
- canSwipeRight={selectedIndex < sections.length - 1}
- onSwipeEnd={onSwipeEnd}>
- item._reactKey}
- renderItem={renderItemInternal}
- ListFooterComponent={ListFooterComponent}
- stickyHeaderIndices={STICKY_HEADER_INDICES}
- refreshing={refreshing}
- onScroll={onScroll}
- onRefresh={onRefresh}
- onEndReached={onEndReached}
- onEndReachedThreshold={0.6}
- contentContainerStyle={s.contentContainer}
- removeClippedSubviews={true}
- scrollIndicatorInsets={{right: 1}} // fixes a bug where the scroll indicator is on the middle of the screen https://github.com/bluesky-social/social-app/pull/464
- />
-
+
)
}
+
+export function Selector({
+ selectedIndex,
+ items,
+ onSelect,
+}: {
+ selectedIndex: number
+ items: string[]
+ onSelect?: (index: number) => void
+}) {
+ const pal = usePalette('default')
+ const borderColor = useColorSchemeStyle(
+ {borderColor: colors.black},
+ {borderColor: colors.white},
+ )
+
+ const onPressItem = (index: number) => {
+ onSelect?.(index)
+ }
+
+ return (
+
+ {items.map((item, i) => {
+ const selected = i === selectedIndex
+ return (
+ onPressItem(i)}>
+
+
+ {item}
+
+
+
+ )
+ })}
+
+ )
+}
+
+const styles = StyleSheet.create({
+ outer: {
+ flexDirection: 'row',
+ paddingHorizontal: 14,
+ },
+ item: {
+ marginRight: 14,
+ paddingHorizontal: 10,
+ paddingTop: 8,
+ paddingBottom: 12,
+ },
+ itemSelected: {
+ borderBottomWidth: 3,
+ },
+ label: {
+ fontWeight: '600',
+ },
+ labelSelected: {
+ fontWeight: '600',
+ },
+ underline: {
+ position: 'absolute',
+ height: 4,
+ bottom: 0,
+ },
+})
diff --git a/src/view/com/util/gestures/HorzSwipe.tsx b/src/view/com/util/gestures/HorzSwipe.tsx
deleted file mode 100644
index 09f6c345..00000000
--- a/src/view/com/util/gestures/HorzSwipe.tsx
+++ /dev/null
@@ -1,157 +0,0 @@
-import React, {useState} from 'react'
-import {
- Animated,
- GestureResponderEvent,
- I18nManager,
- PanResponder,
- PanResponderGestureState,
- useWindowDimensions,
- View,
-} from 'react-native'
-import {clamp} from 'lodash'
-import {s} from 'lib/styles'
-
-interface Props {
- panX: Animated.Value
- canSwipeLeft?: boolean
- canSwipeRight?: boolean
- swipeEnabled?: boolean
- hasPriority?: boolean // if has priority, will not release control of the gesture to another gesture
- distThresholdDivisor?: number
- useNativeDriver?: boolean
- onSwipeStart?: () => void
- onSwipeStartDirection?: (dx: number) => void
- onSwipeEnd?: (dx: number) => void
- children: React.ReactNode
-}
-
-export function HorzSwipe({
- panX,
- canSwipeLeft = false,
- canSwipeRight = false,
- swipeEnabled = true,
- hasPriority = false,
- distThresholdDivisor = 1.75,
- useNativeDriver = false,
- onSwipeStart,
- onSwipeStartDirection,
- onSwipeEnd,
- children,
-}: Props) {
- const winDim = useWindowDimensions()
- const [dir, setDir] = useState(0)
-
- const swipeVelocityThreshold = 35
- const swipeDistanceThreshold = winDim.width / distThresholdDivisor
-
- const isMovingHorizontally = (
- _: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- return (
- Math.abs(gestureState.dx) > Math.abs(gestureState.dy * 1.25) &&
- Math.abs(gestureState.vx) > Math.abs(gestureState.vy * 1.25)
- )
- }
-
- const canMoveScreen = (
- event: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- if (swipeEnabled === false) {
- return false
- }
-
- const diffX = I18nManager.isRTL ? -gestureState.dx : gestureState.dx
- const willHandle =
- isMovingHorizontally(event, gestureState) &&
- ((diffX > 0 && canSwipeLeft) || (diffX < 0 && canSwipeRight))
- return willHandle
- }
-
- const startGesture = () => {
- setDir(0)
- onSwipeStart?.()
-
- panX.stopAnimation()
- // @ts-expect-error: _value is private, but docs use it as well
- panX.setOffset(panX._value)
- }
-
- const respondToGesture = (
- _: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- const diffX = I18nManager.isRTL ? -gestureState.dx : gestureState.dx
-
- if (
- // swiping left
- (diffX > 0 && !canSwipeLeft) ||
- // swiping right
- (diffX < 0 && !canSwipeRight)
- ) {
- panX.setValue(0)
- return
- }
-
- panX.setValue(clamp(diffX / swipeDistanceThreshold, -1, 1) * -1)
-
- const newDir = diffX > 0 ? -1 : diffX < 0 ? 1 : 0
- if (newDir !== dir) {
- setDir(newDir)
- onSwipeStartDirection?.(newDir)
- }
- }
-
- const finishGesture = (
- _: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- if (
- Math.abs(gestureState.dx) > Math.abs(gestureState.dy) &&
- Math.abs(gestureState.vx) > Math.abs(gestureState.vy) &&
- (Math.abs(gestureState.dx) > swipeDistanceThreshold / 4 ||
- Math.abs(gestureState.vx) > swipeVelocityThreshold)
- ) {
- const final = Math.floor(
- (gestureState.dx / Math.abs(gestureState.dx)) * -1,
- )
- Animated.timing(panX, {
- toValue: final,
- duration: 100,
- useNativeDriver,
- isInteraction: false,
- }).start(() => {
- onSwipeEnd?.(final)
- panX.flattenOffset()
- panX.setValue(0)
- })
- } else {
- onSwipeEnd?.(0)
- Animated.timing(panX, {
- toValue: 0,
- duration: 100,
- useNativeDriver,
- isInteraction: false,
- }).start(() => {
- panX.flattenOffset()
- panX.setValue(0)
- })
- }
- }
-
- const panResponder = PanResponder.create({
- onMoveShouldSetPanResponder: canMoveScreen,
- onPanResponderGrant: startGesture,
- onPanResponderMove: respondToGesture,
- onPanResponderTerminate: finishGesture,
- onPanResponderRelease: finishGesture,
- onPanResponderTerminationRequest: () => !hasPriority,
- })
-
- return (
-
- {children}
-
- )
-}
diff --git a/src/view/com/util/gestures/SwipeAndZoom.tsx b/src/view/com/util/gestures/SwipeAndZoom.tsx
deleted file mode 100644
index 75c67901..00000000
--- a/src/view/com/util/gestures/SwipeAndZoom.tsx
+++ /dev/null
@@ -1,302 +0,0 @@
-import React, {useState} from 'react'
-import {
- Animated,
- GestureResponderEvent,
- I18nManager,
- PanResponder,
- PanResponderGestureState,
- useWindowDimensions,
- View,
-} from 'react-native'
-import {clamp} from 'lodash'
-import {s} from 'lib/styles'
-
-export enum Dir {
- None,
- Up,
- Down,
- Left,
- Right,
- Zoom,
-}
-
-interface Props {
- panX: Animated.Value
- panY: Animated.Value
- zoom: Animated.Value
- canSwipeLeft?: boolean
- canSwipeRight?: boolean
- canSwipeUp?: boolean
- canSwipeDown?: boolean
- swipeEnabled?: boolean
- zoomEnabled?: boolean
- hasPriority?: boolean // if has priority, will not release control of the gesture to another gesture
- horzDistThresholdDivisor?: number
- vertDistThresholdDivisor?: number
- useNativeDriver?: boolean
- onSwipeStart?: () => void
- onSwipeStartDirection?: (dir: Dir) => void
- onSwipeEnd?: (dir: Dir) => void
- children: React.ReactNode
-}
-
-export function SwipeAndZoom({
- panX,
- panY,
- zoom,
- canSwipeLeft = false,
- canSwipeRight = false,
- canSwipeUp = false,
- canSwipeDown = false,
- swipeEnabled = false,
- zoomEnabled = false,
- hasPriority = false,
- horzDistThresholdDivisor = 1.75,
- vertDistThresholdDivisor = 1.75,
- useNativeDriver = false,
- onSwipeStart,
- onSwipeStartDirection,
- onSwipeEnd,
- children,
-}: Props) {
- const winDim = useWindowDimensions()
- const [dir, setDir] = useState(Dir.None)
- const [initialDistance, setInitialDistance] = useState(
- undefined,
- )
-
- const swipeVelocityThreshold = 35
- const swipeHorzDistanceThreshold = winDim.width / horzDistThresholdDivisor
- const swipeVertDistanceThreshold = winDim.height / vertDistThresholdDivisor
-
- const isMovingHorizontally = (
- _: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- return (
- Math.abs(gestureState.dx) > Math.abs(gestureState.dy * 1.25) &&
- Math.abs(gestureState.vx) > Math.abs(gestureState.vy * 1.25)
- )
- }
- const isMovingVertically = (
- _: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- return (
- Math.abs(gestureState.dy) > Math.abs(gestureState.dx * 1.25) &&
- Math.abs(gestureState.vy) > Math.abs(gestureState.vx * 1.25)
- )
- }
-
- const canDir = (d: Dir) => {
- if (d === Dir.Left) {
- return canSwipeLeft
- }
- if (d === Dir.Right) {
- return canSwipeRight
- }
- if (d === Dir.Up) {
- return canSwipeUp
- }
- if (d === Dir.Down) {
- return canSwipeDown
- }
- if (d === Dir.Zoom) {
- return zoomEnabled
- }
- return false
- }
- const isHorz = (d: Dir) => d === Dir.Left || d === Dir.Right
- const isVert = (d: Dir) => d === Dir.Up || d === Dir.Down
-
- const canMoveScreen = (
- event: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- if (zoomEnabled && gestureState.numberActiveTouches === 2) {
- return true
- } else if (swipeEnabled && gestureState.numberActiveTouches === 1) {
- const dx = I18nManager.isRTL ? -gestureState.dx : gestureState.dx
- const dy = gestureState.dy
- const willHandle =
- (isMovingHorizontally(event, gestureState) &&
- ((dx > 0 && canSwipeLeft) || (dx < 0 && canSwipeRight))) ||
- (isMovingVertically(event, gestureState) &&
- ((dy > 0 && canSwipeUp) || (dy < 0 && canSwipeDown)))
- return willHandle
- }
- return false
- }
-
- const startGesture = () => {
- setDir(Dir.None)
- onSwipeStart?.()
-
- // reset all state
- panX.stopAnimation()
- // @ts-expect-error: _value is private, but docs use it as well
- panX.setOffset(panX._value)
- panY.stopAnimation()
- // @ts-expect-error: _value is private, but docs use it as well
- panY.setOffset(panY._value)
- zoom.stopAnimation()
- // @ts-expect-error: _value is private, but docs use it as well
- zoom.setOffset(zoom._value)
- setInitialDistance(undefined)
- }
-
- const respondToGesture = (
- e: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- const dx = I18nManager.isRTL ? -gestureState.dx : gestureState.dx
- const dy = gestureState.dy
-
- let newDir = Dir.None
- if (dir === Dir.None) {
- // establish if the user is swiping horz or vert, or zooming
- if (gestureState.numberActiveTouches === 2) {
- newDir = Dir.Zoom
- } else if (Math.abs(dx) > Math.abs(dy)) {
- newDir = dx > 0 ? Dir.Left : Dir.Right
- } else {
- newDir = dy > 0 ? Dir.Up : Dir.Down
- }
- } else if (isHorz(dir)) {
- // direction update
- newDir = dx > 0 ? Dir.Left : Dir.Right
- } else if (isVert(dir)) {
- // direction update
- newDir = dy > 0 ? Dir.Up : Dir.Down
- } else {
- newDir = dir
- }
-
- if (newDir === Dir.Zoom) {
- if (zoomEnabled) {
- if (gestureState.numberActiveTouches === 2) {
- // zoom in/out
- const x0 = e.nativeEvent.touches[0].pageX
- const x1 = e.nativeEvent.touches[1].pageX
- const y0 = e.nativeEvent.touches[0].pageY
- const y1 = e.nativeEvent.touches[1].pageY
- const zoomDx = Math.abs(x0 - x1)
- const zoomDy = Math.abs(y0 - y1)
- const dist = Math.sqrt(zoomDx * zoomDx + zoomDy * zoomDy) / 100
- if (
- typeof initialDistance === 'undefined' ||
- dist - initialDistance < 0
- ) {
- setInitialDistance(dist)
- } else {
- zoom.setValue(dist - initialDistance)
- }
- } else {
- // pan around after zooming
- panX.setValue(clamp(dx / winDim.width, -1, 1) * -1)
- panY.setValue(clamp(dy / winDim.height, -1, 1) * -1)
- }
- }
- } else if (isHorz(newDir)) {
- // swipe left/right
- panX.setValue(
- clamp(
- dx / swipeHorzDistanceThreshold,
- canSwipeRight ? -1 : 0,
- canSwipeLeft ? 1 : 0,
- ) * -1,
- )
- panY.setValue(0)
- } else if (isVert(newDir)) {
- // swipe up/down
- panY.setValue(
- clamp(
- dy / swipeVertDistanceThreshold,
- canSwipeDown ? -1 : 0,
- canSwipeUp ? 1 : 0,
- ) * -1,
- )
- panX.setValue(0)
- }
-
- if (!canDir(newDir)) {
- newDir = Dir.None
- }
- if (newDir !== dir) {
- setDir(newDir)
- onSwipeStartDirection?.(newDir)
- }
- }
-
- const finishGesture = (
- _: GestureResponderEvent,
- gestureState: PanResponderGestureState,
- ) => {
- const finish = (finalDir: Dir) => () => {
- if (finalDir !== Dir.None) {
- onSwipeEnd?.(finalDir)
- }
- setDir(Dir.None)
- panX.flattenOffset()
- panX.setValue(0)
- panY.flattenOffset()
- panY.setValue(0)
- }
- if (
- isHorz(dir) &&
- (Math.abs(gestureState.dx) > swipeHorzDistanceThreshold / 4 ||
- Math.abs(gestureState.vx) > swipeVelocityThreshold)
- ) {
- // horizontal swipe reset
- Animated.timing(panX, {
- toValue: dir === Dir.Left ? -1 : 1,
- duration: 100,
- useNativeDriver,
- }).start(finish(dir))
- } else if (
- isVert(dir) &&
- (Math.abs(gestureState.dy) > swipeVertDistanceThreshold / 8 ||
- Math.abs(gestureState.vy) > swipeVelocityThreshold)
- ) {
- // vertical swipe reset
- Animated.timing(panY, {
- toValue: dir === Dir.Up ? -1 : 1,
- duration: 100,
- useNativeDriver,
- }).start(finish(dir))
- } else {
- // zoom (or no direction) reset
- onSwipeEnd?.(Dir.None)
- Animated.timing(panX, {
- toValue: 0,
- duration: 100,
- useNativeDriver,
- }).start()
- Animated.timing(panY, {
- toValue: 0,
- duration: 100,
- useNativeDriver,
- }).start()
- Animated.timing(zoom, {
- toValue: 0,
- duration: 100,
- useNativeDriver,
- }).start()
- }
- }
-
- const panResponder = PanResponder.create({
- onMoveShouldSetPanResponder: canMoveScreen,
- onPanResponderGrant: startGesture,
- onPanResponderMove: respondToGesture,
- onPanResponderTerminate: finishGesture,
- onPanResponderRelease: finishGesture,
- onPanResponderTerminationRequest: () => !hasPriority,
- })
-
- return (
-
- {children}
-
- )
-}
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index 3b4c47ce..cd6c72ff 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -18,7 +18,6 @@ import {EmptyState} from '../com/util/EmptyState'
import {Text} from '../com/util/text/Text'
import {FAB} from '../com/util/fab/FAB'
import {s, colors} from 'lib/styles'
-import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
import {useAnalytics} from 'lib/analytics'
import {ComposeIcon2} from 'lib/icons'
@@ -32,7 +31,6 @@ export const ProfileScreen = withAuthRequired(
screen('Profile')
}, [screen])
- const onMainScroll = useOnMainScroll(store)
const [hasSetup, setHasSetup] = useState(false)
const uiState = React.useMemo(
() => new ProfileUiModel(store, {user: route.params.name}),
@@ -68,9 +66,12 @@ export const ProfileScreen = withAuthRequired(
track('ProfileScreen:PressCompose')
store.shell.openComposer({})
}, [store, track])
- const onSelectView = (index: number) => {
- uiState.setSelectedViewIndex(index)
- }
+ const onSelectView = React.useCallback(
+ (index: number) => {
+ uiState.setSelectedViewIndex(index)
+ },
+ [uiState],
+ )
const onRefresh = React.useCallback(() => {
uiState
.refresh()
@@ -158,7 +159,6 @@ export const ProfileScreen = withAuthRequired(
ListFooterComponent={Footer}
refreshing={uiState.isRefreshing || false}
onSelectView={onSelectView}
- onScroll={onMainScroll}
onRefresh={onRefresh}
onEndReached={onEndReached}
/>