merge main
This commit is contained in:
@@ -1,23 +1,15 @@
|
||||
import {interpolate, useAnimatedStyle} from 'react-native-reanimated'
|
||||
import {useMinimalShellMode as useMinimalShellModeState} from '#/state/shell/minimal-mode'
|
||||
|
||||
import {useMinimalShellMode} from '#/state/shell/minimal-mode'
|
||||
import {useShellLayout} from '#/state/shell/shell-layout'
|
||||
|
||||
export function useMinimalShellMode() {
|
||||
const mode = useMinimalShellModeState()
|
||||
const {footerHeight, headerHeight} = useShellLayout()
|
||||
// Keep these separated so that we only pay for useAnimatedStyle that gets used.
|
||||
|
||||
const footerMinimalShellTransform = useAnimatedStyle(() => {
|
||||
return {
|
||||
pointerEvents: mode.value === 0 ? 'auto' : 'none',
|
||||
opacity: Math.pow(1 - mode.value, 2),
|
||||
transform: [
|
||||
{
|
||||
translateY: interpolate(mode.value, [0, 1], [0, footerHeight.value]),
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
const headerMinimalShellTransform = useAnimatedStyle(() => {
|
||||
export function useMinimalShellHeaderTransform() {
|
||||
const mode = useMinimalShellMode()
|
||||
const {headerHeight} = useShellLayout()
|
||||
|
||||
const headerTransform = useAnimatedStyle(() => {
|
||||
return {
|
||||
pointerEvents: mode.value === 0 ? 'auto' : 'none',
|
||||
opacity: Math.pow(1 - mode.value, 2),
|
||||
@@ -28,7 +20,32 @@ export function useMinimalShellMode() {
|
||||
],
|
||||
}
|
||||
})
|
||||
const fabMinimalShellTransform = useAnimatedStyle(() => {
|
||||
|
||||
return headerTransform
|
||||
}
|
||||
|
||||
export function useMinimalShellFooterTransform() {
|
||||
const mode = useMinimalShellMode()
|
||||
const {footerHeight} = useShellLayout()
|
||||
|
||||
const footerTransform = useAnimatedStyle(() => {
|
||||
return {
|
||||
pointerEvents: mode.value === 0 ? 'auto' : 'none',
|
||||
opacity: Math.pow(1 - mode.value, 2),
|
||||
transform: [
|
||||
{
|
||||
translateY: interpolate(mode.value, [0, 1], [0, footerHeight.value]),
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
return footerTransform
|
||||
}
|
||||
|
||||
export function useMinimalShellFabTransform() {
|
||||
const mode = useMinimalShellMode()
|
||||
|
||||
const fabTransform = useAnimatedStyle(() => {
|
||||
return {
|
||||
transform: [
|
||||
{
|
||||
@@ -37,9 +54,5 @@ export function useMinimalShellMode() {
|
||||
],
|
||||
}
|
||||
})
|
||||
return {
|
||||
footerMinimalShellTransform,
|
||||
headerMinimalShellTransform,
|
||||
fabMinimalShellTransform,
|
||||
}
|
||||
return fabTransform
|
||||
}
|
||||
@@ -3,5 +3,4 @@ export type Gate =
|
||||
| 'request_notifications_permission_after_onboarding_v2'
|
||||
| 'show_avi_follow_button'
|
||||
| 'show_follow_back_label_v2'
|
||||
| 'show_notification_badge_mobile_web'
|
||||
| 'starter_packs_enabled'
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
useInfiniteQuery,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
import throttle from 'lodash.throttle'
|
||||
|
||||
import {useCurrentConvoId} from '#/state/messages/current-convo-id'
|
||||
import {useMessagesEventBus} from '#/state/messages/events'
|
||||
@@ -89,6 +90,15 @@ export function ListConvosProviderInner({
|
||||
const {currentConvoId} = useCurrentConvoId()
|
||||
const {currentAccount} = useSession()
|
||||
|
||||
const debouncedRefetch = useMemo(
|
||||
() =>
|
||||
throttle(refetch, 500, {
|
||||
leading: true,
|
||||
trailing: true,
|
||||
}),
|
||||
[refetch],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const unsub = messagesBus.on(
|
||||
events => {
|
||||
@@ -96,7 +106,7 @@ export function ListConvosProviderInner({
|
||||
|
||||
events.logs.forEach(log => {
|
||||
if (ChatBskyConvoDefs.isLogBeginConvo(log)) {
|
||||
refetch()
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogLeaveConvo(log)) {
|
||||
queryClient.setQueryData(RQKEY, (old: ConvoListQueryData) =>
|
||||
optimisticDelete(log.convoId, old),
|
||||
@@ -170,7 +180,7 @@ export function ListConvosProviderInner({
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
refetch()
|
||||
debouncedRefetch()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -183,7 +193,14 @@ export function ListConvosProviderInner({
|
||||
)
|
||||
|
||||
return () => unsub()
|
||||
}, [messagesBus, currentConvoId, refetch, queryClient, currentAccount?.did])
|
||||
}, [
|
||||
messagesBus,
|
||||
currentConvoId,
|
||||
refetch,
|
||||
queryClient,
|
||||
currentAccount?.did,
|
||||
debouncedRefetch,
|
||||
])
|
||||
|
||||
const ctx = useMemo(() => {
|
||||
return data?.pages.flatMap(page => page.convos) ?? []
|
||||
|
||||
@@ -405,13 +405,31 @@ export const ComposePost = observer(function ComposePost({
|
||||
// Backup focus on android, if the keyboard *still* refuses to show
|
||||
useEffect(() => {
|
||||
if (!isAndroid) return
|
||||
if (isModalReady) {
|
||||
setTimeout(() => {
|
||||
if (!Keyboard.isVisible()) {
|
||||
textInput.current?.blur()
|
||||
textInput.current?.focus()
|
||||
}
|
||||
}, 300)
|
||||
if (!isModalReady) return
|
||||
|
||||
function tryFocus() {
|
||||
if (!Keyboard.isVisible()) {
|
||||
textInput.current?.blur()
|
||||
textInput.current?.focus()
|
||||
}
|
||||
}
|
||||
|
||||
tryFocus()
|
||||
// Retry with enough gap to avoid interrupting the previous attempt.
|
||||
// Unfortunately we don't know which attempt will succeed.
|
||||
const retryInterval = setInterval(tryFocus, 500)
|
||||
|
||||
function stopTrying() {
|
||||
clearInterval(retryInterval)
|
||||
}
|
||||
|
||||
// Deactivate this fallback as soon as anything happens.
|
||||
const sub1 = Keyboard.addListener('keyboardDidShow', stopTrying)
|
||||
const sub2 = Keyboard.addListener('keyboardDidHide', stopTrying)
|
||||
return () => {
|
||||
clearInterval(retryInterval)
|
||||
sub1.remove()
|
||||
sub2.remove()
|
||||
}
|
||||
}, [isModalReady])
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import {useLingui} from '@lingui/react'
|
||||
import {CogIcon} from '#/lib/icons'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useShellLayout} from '#/state/shell/shell-layout'
|
||||
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellHeaderTransform} from 'lib/hooks/useMinimalShellTransform'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {Logo} from '#/view/icons/Logo'
|
||||
@@ -39,7 +39,7 @@ function HomeHeaderLayoutDesktopAndTablet({
|
||||
tabBarAnchor: JSX.Element | null | undefined
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {headerMinimalShellTransform} = useMinimalShellMode()
|
||||
const headerMinimalShellTransform = useMinimalShellHeaderTransform()
|
||||
const {headerHeight} = useShellLayout()
|
||||
const {hasSession} = useSession()
|
||||
const {_} = useLingui()
|
||||
|
||||
@@ -10,7 +10,7 @@ import {useSession} from '#/state/session'
|
||||
import {useSetDrawerOpen} from '#/state/shell/drawer-open'
|
||||
import {useShellLayout} from '#/state/shell/shell-layout'
|
||||
import {HITSLOP_10} from 'lib/constants'
|
||||
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellHeaderTransform} from 'lib/hooks/useMinimalShellTransform'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {isWeb} from 'platform/detection'
|
||||
import {Logo} from '#/view/icons/Logo'
|
||||
@@ -30,7 +30,7 @@ export function HomeHeaderLayoutMobile({
|
||||
const {_} = useLingui()
|
||||
const setDrawerOpen = useSetDrawerOpen()
|
||||
const {headerHeight} = useShellLayout()
|
||||
const {headerMinimalShellTransform} = useMinimalShellMode()
|
||||
const headerMinimalShellTransform = useMinimalShellHeaderTransform()
|
||||
const {hasSession} = useSession()
|
||||
|
||||
const onPressAvi = React.useCallback(() => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {useSetDrawerOpen} from '#/state/shell'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellHeaderTransform} from 'lib/hooks/useMinimalShellTransform'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {NavigationProp} from 'lib/routes/types'
|
||||
@@ -203,7 +203,7 @@ function Container({
|
||||
showBorder?: boolean
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {headerMinimalShellTransform} = useMinimalShellMode()
|
||||
const headerMinimalShellTransform = useMinimalShellHeaderTransform()
|
||||
|
||||
if (!hideOnScroll) {
|
||||
return (
|
||||
|
||||
@@ -4,7 +4,7 @@ import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {LinearGradient} from 'expo-linear-gradient'
|
||||
|
||||
import {useMinimalShellMode} from '#/lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {gradients} from '#/lib/styles'
|
||||
@@ -20,7 +20,7 @@ export interface FABProps
|
||||
export function FABInner({testID, icon, ...props}: FABProps) {
|
||||
const insets = useSafeAreaInsets()
|
||||
const {isMobile, isTablet} = useWebMediaQueries()
|
||||
const {fabMinimalShellTransform} = useMinimalShellMode()
|
||||
const fabMinimalShellTransform = useMinimalShellFabTransform()
|
||||
const {
|
||||
state: pressed,
|
||||
onIn: onPressIn,
|
||||
|
||||
@@ -6,7 +6,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {useMediaQuery} from 'react-responsive'
|
||||
|
||||
import {HITSLOP_20} from '#/lib/constants'
|
||||
import {useMinimalShellMode} from '#/lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
@@ -30,7 +30,7 @@ export function LoadLatestBtn({
|
||||
const pal = usePalette('default')
|
||||
const {hasSession} = useSession()
|
||||
const {isDesktop, isTablet, isMobile, isTabletOrMobile} = useWebMediaQueries()
|
||||
const {fabMinimalShellTransform} = useMinimalShellMode()
|
||||
const fabMinimalShellTransform = useMinimalShellFabTransform()
|
||||
const insets = useSafeAreaInsets()
|
||||
|
||||
// move button inline if it starts overlapping the left nav
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import {useSession} from '#/state/session'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellFabTransform} from 'lib/hooks/useMinimalShellTransform'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
|
||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||
@@ -26,7 +26,7 @@ type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>
|
||||
export function PostThreadScreen({route}: Props) {
|
||||
const queryClient = useQueryClient()
|
||||
const {hasSession} = useSession()
|
||||
const {fabMinimalShellTransform} = useMinimalShellMode()
|
||||
const fabMinimalShellTransform = useMinimalShellFabTransform()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
const {openComposer} = useComposerControls()
|
||||
const safeAreaInsets = useSafeAreaInsets()
|
||||
|
||||
@@ -10,7 +10,7 @@ import {StackActions} from '@react-navigation/native'
|
||||
import {useAnalytics} from '#/lib/analytics/analytics'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {useDedupe} from '#/lib/hooks/useDedupe'
|
||||
import {useMinimalShellMode} from '#/lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellFooterTransform} from '#/lib/hooks/useMinimalShellTransform'
|
||||
import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
@@ -66,7 +66,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
useNavigationTabState()
|
||||
const numUnreadNotifications = useUnreadNotifications()
|
||||
const numUnreadMessages = useUnreadMessageCount()
|
||||
const {footerMinimalShellTransform} = useMinimalShellMode()
|
||||
const footerMinimalShellTransform = useMinimalShellFooterTransform()
|
||||
const {data: profile} = useProfileQuery({did: currentAccount?.did})
|
||||
const {requestSwitchToAccount} = useLoggedOutViewControls()
|
||||
const closeAllActiveElements = useCloseAllActiveElements()
|
||||
|
||||
@@ -6,7 +6,7 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useNavigationState} from '@react-navigation/native'
|
||||
|
||||
import {useMinimalShellMode} from '#/lib/hooks/useMinimalShellMode'
|
||||
import {useMinimalShellFooterTransform} from '#/lib/hooks/useMinimalShellTransform'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {getCurrentRoute, isTab} from '#/lib/routes/helpers'
|
||||
@@ -16,7 +16,6 @@ import {s} from '#/lib/styles'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||
import {useCloseAllActiveElements} from '#/state/util'
|
||||
import {useGate} from 'lib/statsig/statsig'
|
||||
import {useUnreadMessageCount} from 'state/queries/messages/list-converations'
|
||||
import {useUnreadNotifications} from 'state/queries/notifications/unread'
|
||||
import {Button} from '#/view/com/util/forms/Button'
|
||||
@@ -49,8 +48,7 @@ export function BottomBarWeb() {
|
||||
const {hasSession, currentAccount} = useSession()
|
||||
const pal = usePalette('default')
|
||||
const safeAreaInsets = useSafeAreaInsets()
|
||||
const gate = useGate()
|
||||
const {footerMinimalShellTransform} = useMinimalShellMode()
|
||||
const footerMinimalShellTransform = useMinimalShellFooterTransform()
|
||||
const {requestSwitchToAccount} = useLoggedOutViewControls()
|
||||
const closeAllActiveElements = useCloseAllActiveElements()
|
||||
const iconWidth = 26
|
||||
@@ -115,14 +113,13 @@ export function BottomBarWeb() {
|
||||
width={iconWidth - 1}
|
||||
style={[styles.ctrlIcon, pal.text, styles.messagesIcon]}
|
||||
/>
|
||||
{unreadMessageCount.count > 0 &&
|
||||
gate('show_notification_badge_mobile_web') && (
|
||||
<View style={styles.notificationCount}>
|
||||
<Text style={styles.notificationCountLabel}>
|
||||
{unreadMessageCount.numUnread}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{unreadMessageCount.count > 0 && (
|
||||
<View style={styles.notificationCount}>
|
||||
<Text style={styles.notificationCountLabel}>
|
||||
{unreadMessageCount.numUnread}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}}
|
||||
@@ -136,14 +133,13 @@ export function BottomBarWeb() {
|
||||
width={iconWidth}
|
||||
style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
|
||||
/>
|
||||
{notificationCountStr !== '' &&
|
||||
gate('show_notification_badge_mobile_web') && (
|
||||
<View style={styles.notificationCount}>
|
||||
<Text style={styles.notificationCountLabel}>
|
||||
{notificationCountStr}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{notificationCountStr !== '' && (
|
||||
<View style={styles.notificationCount}>
|
||||
<Text style={styles.notificationCountLabel}>
|
||||
{notificationCountStr}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user