[iPad support] Custom tab navigator for native tablet, with side nav (#3385)
* fix fab position
* show left nav
* custom tab navigator for tablets
* re-disable right nav on tablet
* fix unread count not being rounded
* use mobile subpage header on native tablet
* fix feed being hidden under header
* rename misleading variable name
* remove drawer on native tablet, as on web tablet
* fix prompt styles on tablet
* import isWeb (ts-ignore 😡)
* disable emoji picker on tablet
* prettier format
This commit is contained in:
@@ -484,7 +484,7 @@ export const ComposePost = observer(function ComposePost({
|
||||
<OpenCameraBtn gallery={gallery} />
|
||||
</>
|
||||
) : null}
|
||||
{!isMobile ? (
|
||||
{!isMobile && !isNative ? (
|
||||
<Pressable
|
||||
onPress={onEmojiButtonPress}
|
||||
accessibilityRole="button"
|
||||
|
||||
@@ -7,7 +7,7 @@ import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {getRootNavigation, getTabState, TabState} from '#/lib/routes/helpers'
|
||||
import {logEvent, useGate} from '#/lib/statsig/statsig'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {isNative, isNativeTablet} from '#/platform/detection'
|
||||
import {listenSoftReset} from '#/state/events'
|
||||
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
|
||||
import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
|
||||
@@ -155,9 +155,9 @@ export function FeedPage({
|
||||
}
|
||||
|
||||
function useHeaderOffset() {
|
||||
const {isDesktop, isTablet} = useWebMediaQueries()
|
||||
const {isTabletOrDesktop} = useWebMediaQueries()
|
||||
const {fontScale} = useWindowDimensions()
|
||||
if (isDesktop || isTablet) {
|
||||
if (isTabletOrDesktop && !isNativeTablet) {
|
||||
return 0
|
||||
}
|
||||
const navBarHeight = 42
|
||||
|
||||
@@ -11,7 +11,7 @@ import {useLingui} from '@lingui/react'
|
||||
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
|
||||
import {useSetDrawerOpen} from '#/state/shell/drawer-open'
|
||||
import {useShellLayout} from '#/state/shell/shell-layout'
|
||||
import {isWeb} from 'platform/detection'
|
||||
import {isNativeTablet, isWeb} from 'platform/detection'
|
||||
import {Logo} from '#/view/icons/Logo'
|
||||
|
||||
import {IS_DEV} from '#/env'
|
||||
@@ -42,23 +42,28 @@ export function HomeHeaderLayoutMobile({
|
||||
headerHeight.value = e.nativeEvent.layout.height
|
||||
}}>
|
||||
<View style={[pal.view, styles.topBar]}>
|
||||
<View style={[pal.view, {width: 100}]}>
|
||||
<TouchableOpacity
|
||||
testID="viewHeaderDrawerBtn"
|
||||
onPress={onPressAvi}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Open navigation`)}
|
||||
accessibilityHint={_(
|
||||
msg`Access profile and other navigation links`,
|
||||
)}
|
||||
hitSlop={HITSLOP_10}>
|
||||
<FontAwesomeIcon
|
||||
icon="bars"
|
||||
size={18}
|
||||
color={pal.colors.textLight}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{!isNativeTablet ? (
|
||||
<View style={[pal.view, {width: 100}]}>
|
||||
<TouchableOpacity
|
||||
testID="viewHeaderDrawerBtn"
|
||||
onPress={onPressAvi}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Open navigation`)}
|
||||
accessibilityHint={_(
|
||||
msg`Access profile and other navigation links`,
|
||||
)}
|
||||
hitSlop={HITSLOP_10}>
|
||||
<FontAwesomeIcon
|
||||
icon="bars"
|
||||
size={18}
|
||||
color={pal.colors.textLight}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
) : (
|
||||
// subtract width of LeftNav
|
||||
<View style={{width: 100 - 77}} />
|
||||
)}
|
||||
<View>
|
||||
<Logo width={30} />
|
||||
</View>
|
||||
|
||||
@@ -13,7 +13,7 @@ import {sanitizeHandle} from 'lib/strings/handles'
|
||||
import {makeProfileLink} from 'lib/routes/links'
|
||||
import {NavigationProp} from 'lib/routes/types'
|
||||
import {BACK_HITSLOP} from 'lib/constants'
|
||||
import {isNative} from 'platform/detection'
|
||||
import {isNative, isNativeTablet} from 'platform/detection'
|
||||
import {useLightboxControls, ImagesLightbox} from '#/state/lightbox'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
@@ -71,9 +71,11 @@ export function ProfileSubpageHeader({
|
||||
}
|
||||
}, [openLightbox, avatar])
|
||||
|
||||
const isMobileLayout = isMobile || isNativeTablet
|
||||
|
||||
return (
|
||||
<CenteredView style={pal.view}>
|
||||
{isMobile && (
|
||||
{isMobileLayout && (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
@@ -82,7 +84,7 @@ export function ProfileSubpageHeader({
|
||||
borderBottomWidth: 1,
|
||||
paddingTop: isNative ? 0 : 8,
|
||||
paddingBottom: 8,
|
||||
paddingHorizontal: isMobile ? 12 : 14,
|
||||
paddingHorizontal: isMobileLayout ? 12 : 14,
|
||||
},
|
||||
pal.border,
|
||||
]}>
|
||||
@@ -119,7 +121,7 @@ export function ProfileSubpageHeader({
|
||||
gap: 10,
|
||||
paddingTop: 14,
|
||||
paddingBottom: 6,
|
||||
paddingHorizontal: isMobile ? 12 : 14,
|
||||
paddingHorizontal: isMobileLayout ? 12 : 14,
|
||||
}}>
|
||||
<Pressable
|
||||
testID="headerAviButton"
|
||||
@@ -170,7 +172,7 @@ export function ProfileSubpageHeader({
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
{!isMobile && (
|
||||
{!isMobileLayout && (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
|
||||
@@ -14,7 +14,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {NavigationProp} from 'lib/routes/types'
|
||||
import {useSetDrawerOpen} from '#/state/shell'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {isNativeTablet, isWeb} from '#/platform/detection'
|
||||
|
||||
const BACK_HITSLOP = {left: 20, top: 20, right: 50, bottom: 20}
|
||||
|
||||
@@ -71,13 +71,13 @@ export function SimpleViewHeader({
|
||||
icon="angle-left"
|
||||
style={[styles.backIcon, pal.text]}
|
||||
/>
|
||||
) : (
|
||||
) : !isNativeTablet ? (
|
||||
<FontAwesomeIcon
|
||||
size={18}
|
||||
icon="bars"
|
||||
style={[styles.backIcon, pal.textLight]}
|
||||
/>
|
||||
)}
|
||||
) : null}
|
||||
</TouchableOpacity>
|
||||
) : null}
|
||||
{children}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {FABInner, FABProps} from './FABInner'
|
||||
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {FABInner, FABProps} from './FABInner'
|
||||
|
||||
export const FAB = (_opts: FABProps) => {
|
||||
const {isDesktop} = useWebMediaQueries()
|
||||
|
||||
@@ -4,7 +4,7 @@ import Animated from 'react-native-reanimated'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {LinearGradient} from 'expo-linear-gradient'
|
||||
|
||||
import {isNativeTablet, isWeb} from '#/platform/detection'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {clamp} from 'lib/numbers'
|
||||
@@ -40,7 +40,7 @@ export function FABInner({testID, icon, ...props}: FABProps) {
|
||||
styles.outer,
|
||||
size,
|
||||
tabletSpacing,
|
||||
(isMobile || isNativeTablet) && fabMinimalShellTransform,
|
||||
isMobile && fabMinimalShellTransform,
|
||||
]}>
|
||||
<LinearGradient
|
||||
colors={[gradients.blueLight.start, gradients.blueLight.end]}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from 'react'
|
||||
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
|
||||
import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
|
||||
interface Props {
|
||||
testID?: string
|
||||
|
||||
@@ -4,15 +4,16 @@ import Animated from 'react-native-reanimated'
|
||||
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 {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||
import {colors} from 'lib/styles'
|
||||
import {HITSLOP_20} from '#/lib/constants'
|
||||
import {useMinimalShellMode} from '#/lib/hooks/useMinimalShellMode'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {colors} from '#/lib/styles'
|
||||
import {isNativeTablet, isWeb} from '#/platform/detection'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useTheme} from '#/alf'
|
||||
|
||||
const AnimatedTouchableOpacity =
|
||||
Animated.createAnimatedComponent(TouchableOpacity)
|
||||
import {isNativeTablet, isWeb} from 'platform/detection'
|
||||
import {useSession} from 'state/session'
|
||||
|
||||
export function LoadLatestBtn({
|
||||
onPress,
|
||||
@@ -23,7 +24,7 @@ export function LoadLatestBtn({
|
||||
label: string
|
||||
showIndicator: boolean
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const t = useTheme()
|
||||
const {hasSession} = useSession()
|
||||
const {isDesktop, isTablet, isMobile, isTabletOrMobile} = useWebMediaQueries()
|
||||
const {fabMinimalShellTransform} = useMinimalShellMode()
|
||||
@@ -33,9 +34,7 @@ export function LoadLatestBtn({
|
||||
|
||||
// Adjust height of the fab if we have a session only on mobile web. If we don't have a session, we want to adjust
|
||||
// it on both tablet and mobile since we are showing the bottom bar (see createNativeStackNavigatorWithAuth)
|
||||
const showBottomBar = hasSession
|
||||
? isMobile || isNativeTablet
|
||||
: isTabletOrMobile
|
||||
const showBottomBar = hasSession ? isMobile : isTabletOrMobile
|
||||
|
||||
return (
|
||||
<AnimatedTouchableOpacity
|
||||
@@ -46,8 +45,8 @@ export function LoadLatestBtn({
|
||||
? styles.loadLatestOutOfLine
|
||||
: styles.loadLatestInline),
|
||||
isTablet && !isNativeTablet && styles.loadLatestInline,
|
||||
pal.borderDark,
|
||||
pal.view,
|
||||
t.atoms.border_contrast_high,
|
||||
t.atoms.bg,
|
||||
showBottomBar && fabMinimalShellTransform,
|
||||
]}
|
||||
onPress={onPress}
|
||||
@@ -55,8 +54,10 @@ export function LoadLatestBtn({
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={label}
|
||||
accessibilityHint="">
|
||||
<FontAwesomeIcon icon="angle-up" color={pal.colors.text} size={19} />
|
||||
{showIndicator && <View style={[styles.indicator, pal.borderDark]} />}
|
||||
<FontAwesomeIcon icon="angle-up" color={t.atoms.text.color} size={19} />
|
||||
{showIndicator && (
|
||||
<View style={[styles.indicator, t.atoms.border_contrast_high]} />
|
||||
)}
|
||||
</AnimatedTouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user