| ... | @@ -25,6 +25,7 @@ import { | ... | @@ -25,6 +25,7 @@ import { |
| 25 | type NativeSyntheticEvent, | 25 | type NativeSyntheticEvent, |
| 26 | } from "react-native"; | 26 | } from "react-native"; |
| 27 | import { ScrollViewMarker } from "react-native-screens"; | 27 | import { ScrollViewMarker } from "react-native-screens"; |
| | 28 | import { GestureDetector, useNativeGesture } from "react-native-gesture-handler"; |
| 28 | import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; | 29 | import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; |
| 29 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 30 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 30 | | 31 | |
| ... | @@ -280,6 +281,8 @@ export function HomeScreen(props: HomeScreenProps) { | ... | @@ -280,6 +281,8 @@ export function HomeScreen(props: HomeScreenProps) { |
| 280 | const fullSwipeWidth = primaryColumn && columnMetrics ? columnMetrics.width - 20 : undefined; | 281 | const fullSwipeWidth = primaryColumn && columnMetrics ? columnMetrics.width - 20 : undefined; |
| 281 | const queuedThreadKeys = useQueuedThreadKeys(); | 282 | const queuedThreadKeys = useQueuedThreadKeys(); |
| 282 | const openSwipeableRef = useRef<SwipeableMethods | null>(null); | 283 | const openSwipeableRef = useRef<SwipeableMethods | null>(null); |
| | 284 | // Let trackpad scrolling coexist with each row's horizontal swipe gesture. |
| | 285 | const homeScrollGesture = useNativeGesture(); |
| 283 | const insets = useSafeAreaInsets(); | 286 | const insets = useSafeAreaInsets(); |
| 284 | const { fabClearance } = useAndroidControlSizing(); | 287 | const { fabClearance } = useAndroidControlSizing(); |
| 285 | const screenMetrics = useNativeLayoutMetrics(); | 288 | const screenMetrics = useNativeLayoutMetrics(); |
| ... | @@ -807,6 +810,7 @@ export function HomeScreen(props: HomeScreenProps) { | ... | @@ -807,6 +810,7 @@ export function HomeScreen(props: HomeScreenProps) { |
| 807 | onMoveThread={handleMoveThread} | 810 | onMoveThread={handleMoveThread} |
| 808 | onSwipeableClose={handleSwipeableClose} | 811 | onSwipeableClose={handleSwipeableClose} |
| 809 | onSwipeableWillOpen={handleSwipeableWillOpen} | 812 | onSwipeableWillOpen={handleSwipeableWillOpen} |
| | 813 | simultaneousSwipeGesture={homeScrollGesture} |
| 810 | activationKey={item.key} | 814 | activationKey={item.key} |
| 811 | /> | 815 | /> |
| 812 | ); | 816 | ); |
| ... | @@ -826,6 +830,7 @@ export function HomeScreen(props: HomeScreenProps) { | ... | @@ -826,6 +830,7 @@ export function HomeScreen(props: HomeScreenProps) { |
| 826 | handleSwipeableWillOpen, | 830 | handleSwipeableWillOpen, |
| 827 | handleUnsettleThread, | 831 | handleUnsettleThread, |
| 828 | handleSetThreadAutoSettle, | 832 | handleSetThreadAutoSettle, |
| | 833 | homeScrollGesture, |
| 829 | autoSettleOptOutEnvironmentIds, | 834 | autoSettleOptOutEnvironmentIds, |
| 830 | pinningEnvironmentIds, | 835 | pinningEnvironmentIds, |
| 831 | autoSettleOptOutEnvironmentIds, | 836 | autoSettleOptOutEnvironmentIds, |
| ... | @@ -1012,51 +1017,53 @@ export function HomeScreen(props: HomeScreenProps) { | ... | @@ -1012,51 +1017,53 @@ export function HomeScreen(props: HomeScreenProps) { |
| 1012 | rebuilds and `itemsAreEqual` keeps a minute tick (or an unrelated | 1017 | rebuilds and `itemsAreEqual` keeps a minute tick (or an unrelated |
| 1013 | shell update) from re-rendering untouched rows. */} | 1018 | shell update) from re-rendering untouched rows. */} |
| 1014 | <SwipeableScrollGateProvider enabled={swipeEnabled} activation={swipeRowActivation}> | 1019 | <SwipeableScrollGateProvider enabled={swipeEnabled} activation={swipeRowActivation}> |
| 1015 | <LegendList | 1020 | <GestureDetector gesture={homeScrollGesture}> |
| 1016 | ref={listRef} | 1021 | <LegendList |
| 1017 | onLoad={() => activateVisibleRows(threadListV2Items)} | 1022 | ref={listRef} |
| 1018 | onTouchStart={(event) => trackListTouches(event, true)} | 1023 | onLoad={() => activateVisibleRows(threadListV2Items)} |
| 1019 | onTouchEnd={(event) => trackListTouches(event, false)} | 1024 | onTouchStart={(event) => trackListTouches(event, true)} |
| 1020 | onTouchCancel={(event) => trackListTouches(event, false)} | 1025 | onTouchEnd={(event) => trackListTouches(event, false)} |
| 1021 | renderScrollComponent={Platform.OS === "ios" ? renderHomeScrollView : undefined} | 1026 | onTouchCancel={(event) => trackListTouches(event, false)} |
| 1022 | data={threadListV2Items} | 1027 | renderScrollComponent={Platform.OS === "ios" ? renderHomeScrollView : undefined} |
| 1023 | renderItem={renderV2Item} | 1028 | data={threadListV2Items} |
| 1024 | keyExtractor={v2KeyExtractor} | 1029 | renderItem={renderV2Item} |
| 1025 | getItemType={(item) => item.type} | 1030 | keyExtractor={v2KeyExtractor} |
| 1026 | itemsAreEqual={threadListV2ListItemsAreEqual} | 1031 | getItemType={(item) => item.type} |
| 1027 | estimatedItemSize={ESTIMATED_THREAD_LIST_V2_ROW_HEIGHT} | 1032 | itemsAreEqual={threadListV2ListItemsAreEqual} |
| 1028 | drawDistance={THREAD_LIST_V2_DRAW_DISTANCE} | 1033 | estimatedItemSize={ESTIMATED_THREAD_LIST_V2_ROW_HEIGHT} |
| 1029 | recycleItems | 1034 | drawDistance={THREAD_LIST_V2_DRAW_DISTANCE} |
| 1030 | extraData={v2ExtraData} | 1035 | recycleItems |
| 1031 | ListHeaderComponent={v2ListHeader} | 1036 | extraData={v2ExtraData} |
| 1032 | ListFooterComponent={ | 1037 | ListHeaderComponent={v2ListHeader} |
| 1033 | settledShelfExpanded && threadListV2Layout.hiddenSettledCount > 0 ? ( | 1038 | ListFooterComponent={ |
| 1034 | <ThreadListV2ShowMoreRow | 1039 | settledShelfExpanded && threadListV2Layout.hiddenSettledCount > 0 ? ( |
| 1035 | hiddenCount={threadListV2Layout.hiddenSettledCount} | 1040 | <ThreadListV2ShowMoreRow |
| 1036 | onPress={showMoreSettled} | 1041 | hiddenCount={threadListV2Layout.hiddenSettledCount} |
| 1037 | /> | 1042 | onPress={showMoreSettled} |
| 1038 | ) : null | 1043 | /> |
| 1039 | } | 1044 | ) : null |
| 1040 | ListEmptyComponent={v2ListEmpty} | 1045 | } |
| 1041 | style={{ flex: 1 }} | 1046 | ListEmptyComponent={v2ListEmpty} |
| 1042 | automaticallyAdjustsScrollIndicatorInsets={Platform.OS === "ios"} | 1047 | style={{ flex: 1 }} |
| 1043 | contentInsetAdjustmentBehavior="never" | 1048 | automaticallyAdjustsScrollIndicatorInsets={Platform.OS === "ios"} |
| 1044 | contentInset={Platform.OS === "ios" ? { top: insets.top } : undefined} | 1049 | contentInsetAdjustmentBehavior="never" |
| 1045 | contentInsetStartAdjustment={Platform.OS === "ios" ? insets.top : 0} | 1050 | contentInset={Platform.OS === "ios" ? { top: insets.top } : undefined} |
| 1046 | showsVerticalScrollIndicator={false} | 1051 | contentInsetStartAdjustment={Platform.OS === "ios" ? insets.top : 0} |
| 1047 | keyboardDismissMode="on-drag" | 1052 | showsVerticalScrollIndicator={false} |
| 1048 | keyboardShouldPersistTaps="handled" | 1053 | keyboardDismissMode="on-drag" |
| 1049 | {...scrollGateHandlers} | 1054 | keyboardShouldPersistTaps="handled" |
| 1050 | scrollEventThrottle={16} | 1055 | {...scrollGateHandlers} |
| 1051 | contentContainerStyle={{ | 1056 | scrollEventThrottle={16} |
| 1052 | paddingLeft: (contentSideInsets?.left ?? 0) + (primaryColumn ? 8 : 0), | 1057 | contentContainerStyle={{ |
| 1053 | paddingRight: (contentSideInsets?.right ?? 0) + (primaryColumn ? 8 : 0), | 1058 | paddingLeft: (contentSideInsets?.left ?? 0) + (primaryColumn ? 8 : 0), |
| 1054 | paddingBottom: | 1059 | paddingRight: (contentSideInsets?.right ?? 0) + (primaryColumn ? 8 : 0), |
| 1055 | Platform.OS === "ios" | 1060 | paddingBottom: |
| 1056 | ? iosBottomClearance | 1061 | Platform.OS === "ios" |
| 1057 | : Math.max(insets.bottom, 16) + (Platform.OS === "android" ? fabClearance : 88), | 1062 | ? iosBottomClearance |
| 1058 | }} | 1063 | : Math.max(insets.bottom, 16) + (Platform.OS === "android" ? fabClearance : 88), |
| 1059 | /> | 1064 | }} |
| | 1065 | /> |
| | 1066 | </GestureDetector> |
| 1060 | </SwipeableScrollGateProvider> | 1067 | </SwipeableScrollGateProvider> |
| 1061 | </View> | 1068 | </View> |
| 1062 | </View> | 1069 | </View> |