Improve Device Detection For Better Responsiveness (#1512)

* Refactor `useOnMainScroll` function to use responsive device detection

- Replace static `isDesktopWeb` with `useWebMediaQueries` hook to enable dynamic device type detection.
- Create `useDeviceLimits` hook to dynamically determine `DY_LIMIT_UP` and `DY_LIMIT_DOWN` based on device type.
- Update dependency arrays for the `useCallback` hooks to include new dynamic variables.

* Refactor styles to be responsive to device type

- Create `useStyles` hook that generates styles object based on device type detected from `useWebMediaQueries`.
- Replace static styles object with dynamic styles object generated from `useStyles` hook in components.
- This allows `paddingLeft` values for 'ul' and 'ol' styles to adapt to device type dynamically.
- This allows `maxWidth` values for 'metaItem'' styles to adapt to device type dynamically.

* Remove `isDesktopWeb` in favor of `useWebMediaQueries().isDesktop`

* Refactor `SplashScreen` component for responsive design

* Revision based on review results

* Fix isNative check

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
zio/stable
Bryan Lee 2023-09-29 03:47:34 +08:00 committed by GitHub
parent 2e5f73ff61
commit 2aae37d67b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 289 additions and 244 deletions

View File

@ -2,12 +2,18 @@ import {useState, useCallback, useRef} from 'react'
import {NativeSyntheticEvent, NativeScrollEvent} from 'react-native' import {NativeSyntheticEvent, NativeScrollEvent} from 'react-native'
import {RootStoreModel} from 'state/index' import {RootStoreModel} from 'state/index'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {isDesktopWeb} from 'platform/detection' import {useWebMediaQueries} from './useWebMediaQueries'
const DY_LIMIT_UP = isDesktopWeb ? 30 : 10
const DY_LIMIT_DOWN = isDesktopWeb ? 150 : 10
const Y_LIMIT = 10 const Y_LIMIT = 10
const useDeviceLimits = () => {
const {isDesktop} = useWebMediaQueries()
return {
dyLimitUp: isDesktop ? 30 : 10,
dyLimitDown: isDesktop ? 150 : 10,
}
}
export type OnScrollCb = ( export type OnScrollCb = (
event: NativeSyntheticEvent<NativeScrollEvent>, event: NativeSyntheticEvent<NativeScrollEvent>,
) => void ) => void
@ -18,6 +24,8 @@ export function useOnMainScroll(
): [OnScrollCb, boolean, ResetCb] { ): [OnScrollCb, boolean, ResetCb] {
let lastY = useRef(0) let lastY = useRef(0)
let [isScrolledDown, setIsScrolledDown] = useState(false) let [isScrolledDown, setIsScrolledDown] = useState(false)
const {dyLimitUp, dyLimitDown} = useDeviceLimits()
return [ return [
useCallback( useCallback(
(event: NativeSyntheticEvent<NativeScrollEvent>) => { (event: NativeSyntheticEvent<NativeScrollEvent>) => {
@ -25,15 +33,11 @@ export function useOnMainScroll(
const dy = y - (lastY.current || 0) const dy = y - (lastY.current || 0)
lastY.current = y lastY.current = y
if ( if (!store.shell.minimalShellMode && dy > dyLimitDown && y > Y_LIMIT) {
!store.shell.minimalShellMode &&
dy > DY_LIMIT_DOWN &&
y > Y_LIMIT
) {
store.shell.setMinimalShellMode(true) store.shell.setMinimalShellMode(true)
} else if ( } else if (
store.shell.minimalShellMode && store.shell.minimalShellMode &&
(dy < DY_LIMIT_UP * -1 || y <= Y_LIMIT) (dy < dyLimitUp * -1 || y <= Y_LIMIT)
) { ) {
store.shell.setMinimalShellMode(false) store.shell.setMinimalShellMode(false)
} }
@ -50,7 +54,7 @@ export function useOnMainScroll(
setIsScrolledDown(false) setIsScrolledDown(false)
} }
}, },
[store, isScrolledDown], [store.shell, dyLimitDown, dyLimitUp, isScrolledDown],
), ),
isScrolledDown, isScrolledDown,
useCallback(() => { useCallback(() => {

View File

@ -12,7 +12,6 @@ export const isMobileWeb =
isWeb && isWeb &&
// @ts-ignore we know window exists -prf // @ts-ignore we know window exists -prf
global.window.matchMedia(isMobileWebMediaQuery)?.matches global.window.matchMedia(isMobileWebMediaQuery)?.matches
export const isDesktopWeb = isWeb && !isMobileWeb
export const deviceLocales = dedupArray( export const deviceLocales = dedupArray(
getLocales?.().map?.(locale => locale.languageCode), getLocales?.().map?.(locale => locale.languageCode),

View File

@ -6,7 +6,8 @@ import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
import {s, colors} from 'lib/styles' import {s, colors} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {CenteredView} from '../util/Views' import {CenteredView} from '../util/Views'
import {isMobileWeb} from 'platform/detection' import {isWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
export const SplashScreen = ({ export const SplashScreen = ({
onPressSignin, onPressSignin,
@ -16,6 +17,9 @@ export const SplashScreen = ({
onPressCreateAccount: () => void onPressCreateAccount: () => void
}) => { }) => {
const pal = usePalette('default') const pal = usePalette('default')
const {isTabletOrMobile} = useWebMediaQueries()
const styles = useStyles()
const isMobileWeb = isWeb && isTabletOrMobile
return ( return (
<CenteredView style={[styles.container, pal.view]}> <CenteredView style={[styles.container, pal.view]}>
@ -55,13 +59,14 @@ export const SplashScreen = ({
</View> </View>
</ErrorBoundary> </ErrorBoundary>
</View> </View>
<Footer /> <Footer styles={styles} />
</CenteredView> </CenteredView>
) )
} }
function Footer() { function Footer({styles}: {styles: ReturnType<typeof useStyles>}) {
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<View style={[styles.footer, pal.view, pal.border]}> <View style={[styles.footer, pal.view, pal.border]}>
<TextLink <TextLink
@ -82,78 +87,81 @@ function Footer() {
</View> </View>
) )
} }
const useStyles = () => {
const styles = StyleSheet.create({ const {isTabletOrMobile} = useWebMediaQueries()
container: { const isMobileWeb = isWeb && isTabletOrMobile
height: '100%', return StyleSheet.create({
}, container: {
containerInner: { height: '100%',
height: '100%', },
justifyContent: 'center', containerInner: {
// @ts-ignore web only height: '100%',
paddingBottom: '20vh', justifyContent: 'center',
paddingHorizontal: 20, // @ts-ignore web only
}, paddingBottom: '20vh',
containerInnerMobile: { paddingHorizontal: 20,
paddingBottom: 50, },
}, containerInnerMobile: {
title: { paddingBottom: 50,
textAlign: 'center', },
color: colors.blue3, title: {
fontSize: 68, textAlign: 'center',
fontWeight: 'bold', color: colors.blue3,
paddingBottom: 10, fontSize: 68,
}, fontWeight: 'bold',
titleMobile: { paddingBottom: 10,
textAlign: 'center', },
color: colors.blue3, titleMobile: {
fontSize: 58, textAlign: 'center',
fontWeight: 'bold', color: colors.blue3,
}, fontSize: 58,
subtitle: { fontWeight: 'bold',
textAlign: 'center', },
color: colors.gray5, subtitle: {
fontSize: 52, textAlign: 'center',
fontWeight: 'bold', color: colors.gray5,
paddingBottom: 30, fontSize: 52,
}, fontWeight: 'bold',
subtitleMobile: { paddingBottom: 30,
textAlign: 'center', },
color: colors.gray5, subtitleMobile: {
fontSize: 42, textAlign: 'center',
fontWeight: 'bold', color: colors.gray5,
paddingBottom: 30, fontSize: 42,
}, fontWeight: 'bold',
btns: { paddingBottom: 30,
flexDirection: isMobileWeb ? 'column' : 'row', },
gap: 20, btns: {
justifyContent: 'center', flexDirection: isMobileWeb ? 'column' : 'row',
paddingBottom: 40, gap: 20,
}, justifyContent: 'center',
btn: { paddingBottom: 40,
borderRadius: 30, },
paddingHorizontal: 24, btn: {
paddingVertical: 12, borderRadius: 30,
minWidth: 220, paddingHorizontal: 24,
}, paddingVertical: 12,
btnLabel: { minWidth: 220,
textAlign: 'center', },
fontSize: 18, btnLabel: {
}, textAlign: 'center',
notice: { fontSize: 18,
paddingHorizontal: 40, },
textAlign: 'center', notice: {
}, paddingHorizontal: 40,
footer: { textAlign: 'center',
position: 'absolute', },
left: 0, footer: {
right: 0, position: 'absolute',
bottom: 0, left: 0,
padding: 20, right: 0,
borderTopWidth: 1, bottom: 0,
flexDirection: 'row', padding: 20,
}, borderTopWidth: 1,
footerLink: { flexDirection: 'row',
marginRight: 20, },
}, footerLink: {
}) marginRight: 20,
},
})
}

View File

@ -7,11 +7,11 @@ import {
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {useAnalytics} from 'lib/analytics/analytics' import {useAnalytics} from 'lib/analytics/analytics'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {isDesktopWeb} from 'platform/detection'
import {openCamera} from 'lib/media/picker' import {openCamera} from 'lib/media/picker'
import {useCameraPermission} from 'lib/hooks/usePermissions' import {useCameraPermission} from 'lib/hooks/usePermissions'
import {HITSLOP_10, POST_IMG_MAX} from 'lib/constants' import {HITSLOP_10, POST_IMG_MAX} from 'lib/constants'
import {GalleryModel} from 'state/models/media/gallery' import {GalleryModel} from 'state/models/media/gallery'
import {isMobileWeb, isNative} from 'platform/detection'
type Props = { type Props = {
gallery: GalleryModel gallery: GalleryModel
@ -43,7 +43,8 @@ export function OpenCameraBtn({gallery}: Props) {
} }
}, [gallery, track, store, requestCameraAccessIfNeeded]) }, [gallery, track, store, requestCameraAccessIfNeeded])
if (isDesktopWeb) { const shouldShowCameraButton = isNative || isMobileWeb
if (!shouldShowCameraButton) {
return null return null
} }

View File

@ -6,10 +6,10 @@ import {
} from '@fortawesome/react-native-fontawesome' } from '@fortawesome/react-native-fontawesome'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {useAnalytics} from 'lib/analytics/analytics' import {useAnalytics} from 'lib/analytics/analytics'
import {isDesktopWeb} from 'platform/detection'
import {usePhotoLibraryPermission} from 'lib/hooks/usePermissions' import {usePhotoLibraryPermission} from 'lib/hooks/usePermissions'
import {GalleryModel} from 'state/models/media/gallery' import {GalleryModel} from 'state/models/media/gallery'
import {HITSLOP_10} from 'lib/constants' import {HITSLOP_10} from 'lib/constants'
import {isNative} from 'platform/detection'
type Props = { type Props = {
gallery: GalleryModel gallery: GalleryModel
@ -23,12 +23,12 @@ export function SelectPhotoBtn({gallery}: Props) {
const onPressSelectPhotos = useCallback(async () => { const onPressSelectPhotos = useCallback(async () => {
track('Composer:GalleryOpened') track('Composer:GalleryOpened')
if (!isDesktopWeb && !(await requestPhotoAccessIfNeeded())) { if (isNative && !(await requestPhotoAccessIfNeeded())) {
return return
} }
gallery.pick() gallery.pick()
}, [track, gallery, requestPhotoAccessIfNeeded]) }, [track, requestPhotoAccessIfNeeded, gallery])
return ( return (
<TouchableOpacity <TouchableOpacity

View File

@ -23,7 +23,7 @@ import {ViewHeader} from '../util/ViewHeader'
import {ErrorMessage} from '../util/error/ErrorMessage' import {ErrorMessage} from '../util/error/ErrorMessage'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {isNative, isDesktopWeb} from 'platform/detection' import {isNative} from 'platform/detection'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {useSetTitle} from 'lib/hooks/useSetTitle' import {useSetTitle} from 'lib/hooks/useSetTitle'
import {useNavigation} from '@react-navigation/native' import {useNavigation} from '@react-navigation/native'
@ -78,7 +78,7 @@ export const PostThread = observer(function PostThread({
treeView: boolean treeView: boolean
}) { }) {
const pal = usePalette('default') const pal = usePalette('default')
const {isTablet} = useWebMediaQueries() const {isTablet, isDesktop} = useWebMediaQueries()
const ref = useRef<FlatList>(null) const ref = useRef<FlatList>(null)
const hasScrolledIntoView = useRef<boolean>(false) const hasScrolledIntoView = useRef<boolean>(false)
const [isRefreshing, setIsRefreshing] = React.useState(false) const [isRefreshing, setIsRefreshing] = React.useState(false)
@ -189,7 +189,7 @@ export const PostThread = observer(function PostThread({
} else if (item === REPLY_PROMPT) { } else if (item === REPLY_PROMPT) {
return ( return (
<View> <View>
{isDesktopWeb && <ComposePrompt onPressCompose={onPressReply} />} {isDesktop && <ComposePrompt onPressCompose={onPressReply} />}
</View> </View>
) )
} else if (item === DELETED) { } else if (item === DELETED) {
@ -261,7 +261,20 @@ export const PostThread = observer(function PostThread({
} }
return <></> return <></>
}, },
[onRefresh, onPressReply, pal, posts, isTablet, treeView], [
isTablet,
isDesktop,
onPressReply,
pal.border,
pal.viewLight,
pal.textLight,
pal.view,
pal.text,
pal.colors.border,
posts,
onRefresh,
treeView,
],
) )
// loading // loading

View File

@ -34,7 +34,6 @@ import {usePalette} from 'lib/hooks/usePalette'
import {formatCount} from '../util/numeric/format' import {formatCount} from '../util/numeric/format'
import {TimeElapsed} from 'view/com/util/TimeElapsed' import {TimeElapsed} from 'view/com/util/TimeElapsed'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
export const PostThreadItem = observer(function PostThreadItem({ export const PostThreadItem = observer(function PostThreadItem({
@ -51,6 +50,7 @@ export const PostThreadItem = observer(function PostThreadItem({
const pal = usePalette('default') const pal = usePalette('default')
const store = useStores() const store = useStores()
const [deleted, setDeleted] = React.useState(false) const [deleted, setDeleted] = React.useState(false)
const styles = useStyles()
const record = item.postRecord const record = item.postRecord
const hasEngagement = item.post.likeCount || item.post.repostCount const hasEngagement = item.post.likeCount || item.post.repostCount
@ -568,6 +568,7 @@ function PostOuterWrapper({
}>) { }>) {
const {isMobile} = useWebMediaQueries() const {isMobile} = useWebMediaQueries()
const pal = usePalette('default') const pal = usePalette('default')
const styles = useStyles()
if (treeView && item._depth > 1) { if (treeView && item._depth > 1) {
return ( return (
<View <View
@ -636,90 +637,93 @@ function ExpandedPostDetails({
) )
} }
const styles = StyleSheet.create({ const useStyles = () => {
outer: { const {isDesktop} = useWebMediaQueries()
borderTopWidth: 1, return StyleSheet.create({
paddingLeft: 8, outer: {
}, borderTopWidth: 1,
outerHighlighted: { paddingLeft: 8,
paddingTop: 16, },
paddingLeft: 8, outerHighlighted: {
paddingRight: 8, paddingTop: 16,
}, paddingLeft: 8,
noTopBorder: { paddingRight: 8,
borderTopWidth: 0, },
}, noTopBorder: {
layout: { borderTopWidth: 0,
flexDirection: 'row', },
gap: 10, layout: {
paddingLeft: 8, flexDirection: 'row',
}, gap: 10,
layoutAvi: {}, paddingLeft: 8,
layoutContent: { },
flex: 1, layoutAvi: {},
paddingRight: 10, layoutContent: {
}, flex: 1,
meta: { paddingRight: 10,
flexDirection: 'row', },
paddingTop: 2, meta: {
paddingBottom: 2, flexDirection: 'row',
}, paddingTop: 2,
metaExpandedLine1: { paddingBottom: 2,
paddingTop: 5, },
paddingBottom: 0, metaExpandedLine1: {
}, paddingTop: 5,
metaItem: { paddingBottom: 0,
paddingRight: 5, },
maxWidth: isDesktopWeb ? 380 : 220, metaItem: {
}, paddingRight: 5,
alert: { maxWidth: isDesktop ? 380 : 220,
marginBottom: 6, },
}, alert: {
postTextContainer: { marginBottom: 6,
flexDirection: 'row', },
alignItems: 'center', postTextContainer: {
flexWrap: 'wrap', flexDirection: 'row',
paddingBottom: 4, alignItems: 'center',
paddingRight: 10, flexWrap: 'wrap',
}, paddingBottom: 4,
postTextLargeContainer: { paddingRight: 10,
paddingHorizontal: 0, },
paddingBottom: 10, postTextLargeContainer: {
}, paddingHorizontal: 0,
translateLink: { paddingBottom: 10,
marginBottom: 6, },
}, translateLink: {
contentHider: { marginBottom: 6,
marginBottom: 6, },
}, contentHider: {
contentHiderChild: { marginBottom: 6,
marginTop: 6, },
}, contentHiderChild: {
expandedInfo: { marginTop: 6,
flexDirection: 'row', },
padding: 10, expandedInfo: {
borderTopWidth: 1, flexDirection: 'row',
borderBottomWidth: 1, padding: 10,
marginTop: 5, borderTopWidth: 1,
marginBottom: 15, borderBottomWidth: 1,
}, marginTop: 5,
expandedInfoItem: { marginBottom: 15,
marginRight: 10, },
}, expandedInfoItem: {
loadMore: { marginRight: 10,
flexDirection: 'row', },
alignItems: 'center', loadMore: {
justifyContent: 'flex-start', flexDirection: 'row',
gap: 4, alignItems: 'center',
paddingHorizontal: 20, justifyContent: 'flex-start',
}, gap: 4,
replyLine: { paddingHorizontal: 20,
width: 2, },
marginLeft: 'auto', replyLine: {
marginRight: 'auto', width: 2,
}, marginLeft: 'auto',
cursor: { marginRight: 'auto',
// @ts-ignore web only },
cursor: 'pointer', cursor: {
}, // @ts-ignore web only
}) cursor: 'pointer',
},
})
}

View File

@ -4,13 +4,13 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext' import {useTheme} from 'lib/ThemeContext'
import {Text} from './text/Text' import {Text} from './text/Text'
import {TextLink} from './Link' import {TextLink} from './Link'
import {isDesktopWeb} from 'platform/detection'
import { import {
H1 as ExpoH1, H1 as ExpoH1,
H2 as ExpoH2, H2 as ExpoH2,
H3 as ExpoH3, H3 as ExpoH3,
H4 as ExpoH4, H4 as ExpoH4,
} from '@expo/html-elements' } from '@expo/html-elements'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
/** /**
* These utilities are used to define long documents in an html-like * These utilities are used to define long documents in an html-like
@ -27,30 +27,35 @@ interface IsChildProps {
// | React.ReactNode // | React.ReactNode
export function H1({children}: React.PropsWithChildren<{}>) { export function H1({children}: React.PropsWithChildren<{}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
const typography = useTheme().typography['title-xl'] const typography = useTheme().typography['title-xl']
return <ExpoH1 style={[typography, pal.text, styles.h1]}>{children}</ExpoH1> return <ExpoH1 style={[typography, pal.text, styles.h1]}>{children}</ExpoH1>
} }
export function H2({children}: React.PropsWithChildren<{}>) { export function H2({children}: React.PropsWithChildren<{}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
const typography = useTheme().typography['title-lg'] const typography = useTheme().typography['title-lg']
return <ExpoH2 style={[typography, pal.text, styles.h2]}>{children}</ExpoH2> return <ExpoH2 style={[typography, pal.text, styles.h2]}>{children}</ExpoH2>
} }
export function H3({children}: React.PropsWithChildren<{}>) { export function H3({children}: React.PropsWithChildren<{}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
const typography = useTheme().typography.title const typography = useTheme().typography.title
return <ExpoH3 style={[typography, pal.text, styles.h3]}>{children}</ExpoH3> return <ExpoH3 style={[typography, pal.text, styles.h3]}>{children}</ExpoH3>
} }
export function H4({children}: React.PropsWithChildren<{}>) { export function H4({children}: React.PropsWithChildren<{}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
const typography = useTheme().typography['title-sm'] const typography = useTheme().typography['title-sm']
return <ExpoH4 style={[typography, pal.text, styles.h4]}>{children}</ExpoH4> return <ExpoH4 style={[typography, pal.text, styles.h4]}>{children}</ExpoH4>
} }
export function P({children}: React.PropsWithChildren<{}>) { export function P({children}: React.PropsWithChildren<{}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<Text type="md" style={[pal.text, styles.p]}> <Text type="md" style={[pal.text, styles.p]}>
@ -60,6 +65,7 @@ export function P({children}: React.PropsWithChildren<{}>) {
} }
export function UL({children, isChild}: React.PropsWithChildren<IsChildProps>) { export function UL({children, isChild}: React.PropsWithChildren<IsChildProps>) {
const styles = useStyles()
return ( return (
<View style={[styles.ul, isChild && styles.ulChild]}> <View style={[styles.ul, isChild && styles.ulChild]}>
{markChildProps(children)} {markChildProps(children)}
@ -68,6 +74,7 @@ export function UL({children, isChild}: React.PropsWithChildren<IsChildProps>) {
} }
export function OL({children, isChild}: React.PropsWithChildren<IsChildProps>) { export function OL({children, isChild}: React.PropsWithChildren<IsChildProps>) {
const styles = useStyles()
return ( return (
<View style={[styles.ol, isChild && styles.olChild]}> <View style={[styles.ol, isChild && styles.olChild]}>
{markChildProps(children)} {markChildProps(children)}
@ -79,6 +86,7 @@ export function LI({
children, children,
value, value,
}: React.PropsWithChildren<{value?: string}>) { }: React.PropsWithChildren<{value?: string}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<View style={styles.li}> <View style={styles.li}>
@ -91,6 +99,7 @@ export function LI({
} }
export function A({children, href}: React.PropsWithChildren<{href: string}>) { export function A({children, href}: React.PropsWithChildren<{href: string}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<TextLink <TextLink
@ -112,6 +121,7 @@ export function STRONG({children}: React.PropsWithChildren<{}>) {
} }
export function EM({children}: React.PropsWithChildren<{}>) { export function EM({children}: React.PropsWithChildren<{}>) {
const styles = useStyles()
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<Text type="md" style={[pal.text, styles.em]}> <Text type="md" style={[pal.text, styles.em]}>
@ -132,58 +142,61 @@ function markChildProps(children: React.ReactNode) {
}) })
} }
const styles = StyleSheet.create({ const useStyles = () => {
h1: { const {isDesktop} = useWebMediaQueries()
marginTop: 20, return StyleSheet.create({
marginBottom: 10, h1: {
letterSpacing: 0.8, marginTop: 20,
}, marginBottom: 10,
h2: { letterSpacing: 0.8,
marginTop: 20, },
marginBottom: 10, h2: {
letterSpacing: 0.8, marginTop: 20,
}, marginBottom: 10,
h3: { letterSpacing: 0.8,
marginTop: 0, },
marginBottom: 10, h3: {
}, marginTop: 0,
h4: { marginBottom: 10,
marginTop: 0, },
marginBottom: 10, h4: {
fontWeight: 'bold', marginTop: 0,
}, marginBottom: 10,
p: { fontWeight: 'bold',
marginBottom: 10, },
}, p: {
ul: { marginBottom: 10,
marginBottom: 10, },
paddingLeft: isDesktopWeb ? 18 : 4, ul: {
}, marginBottom: 10,
ulChild: { paddingLeft: isDesktop ? 18 : 4,
paddingTop: 10, },
marginBottom: 0, ulChild: {
}, paddingTop: 10,
ol: { marginBottom: 0,
marginBottom: 10, },
paddingLeft: isDesktopWeb ? 18 : 4, ol: {
}, marginBottom: 10,
olChild: { paddingLeft: isDesktop ? 18 : 4,
paddingTop: 10, },
marginBottom: 0, olChild: {
}, paddingTop: 10,
li: { marginBottom: 0,
flexDirection: 'row', },
paddingRight: 20, li: {
marginBottom: 10, flexDirection: 'row',
}, paddingRight: 20,
liBullet: { marginBottom: 10,
paddingRight: 10, },
}, liBullet: {
liText: {}, paddingRight: 10,
a: { },
marginBottom: 10, liText: {},
}, a: {
em: { marginBottom: 10,
fontStyle: 'italic', },
}, em: {
}) fontStyle: 'italic',
},
})
}

View File

@ -24,10 +24,11 @@ import {NavigationProp} from 'lib/routes/types'
import {router} from '../../../routes' import {router} from '../../../routes'
import {useStores, RootStoreModel} from 'state/index' import {useStores, RootStoreModel} from 'state/index'
import {convertBskyAppUrlIfNeeded, isExternalUrl} from 'lib/strings/url-helpers' import {convertBskyAppUrlIfNeeded, isExternalUrl} from 'lib/strings/url-helpers'
import {isAndroid, isDesktopWeb} from 'platform/detection' import {isAndroid} from 'platform/detection'
import {sanitizeUrl} from '@braintree/sanitize-url' import {sanitizeUrl} from '@braintree/sanitize-url'
import {PressableWithHover} from './PressableWithHover' import {PressableWithHover} from './PressableWithHover'
import FixedTouchableHighlight from '../pager/FixedTouchableHighlight' import FixedTouchableHighlight from '../pager/FixedTouchableHighlight'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
type Event = type Event =
| React.MouseEvent<HTMLAnchorElement, MouseEvent> | React.MouseEvent<HTMLAnchorElement, MouseEvent>
@ -224,7 +225,9 @@ export const DesktopWebTextLink = observer(function DesktopWebTextLink({
lineHeight, lineHeight,
...props ...props
}: DesktopWebTextLinkProps) { }: DesktopWebTextLinkProps) {
if (isDesktopWeb) { const {isDesktop} = useWebMediaQueries()
if (isDesktop) {
return ( return (
<TextLink <TextLink
testID={testID} testID={testID}