Updates to use dynamic/responsive styles on web (#1351)

* Move most responsive queries to the hook

* Fix invalid CSS value

* Fixes to tablet render of post thread

* Fix overflow issues on web

* Fix search header on tablet

* Fix QP margin in web composer

* Fix: only apply double gutter once to flatlist (close #1368)

* Fix styles on discover feeds header

* Fix double discover links in multifeed
This commit is contained in:
Paul Frazee 2023-09-05 10:42:19 -07:00 committed by GitHub
parent be8084ae10
commit 764c7cd569
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 762 additions and 461 deletions

View file

@ -7,7 +7,7 @@ import {Button} from '../com/util/forms/Button'
import * as Toast from '../com/util/Toast'
import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette'
import {isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
@ -23,6 +23,7 @@ export const AppPasswords = withAuthRequired(
const pal = usePalette('default')
const store = useStores()
const {screen} = useAnalytics()
const {isTabletOrDesktop} = useWebMediaQueries()
useFocusEffect(
React.useCallback(() => {
@ -41,7 +42,7 @@ export const AppPasswords = withAuthRequired(
<CenteredView
style={[
styles.container,
isDesktopWeb && styles.containerDesktop,
isTabletOrDesktop && styles.containerDesktop,
pal.view,
pal.border,
]}
@ -53,11 +54,11 @@ export const AppPasswords = withAuthRequired(
pressing the button below.
</Text>
</View>
{!isDesktopWeb && <View style={styles.flex1} />}
{!isTabletOrDesktop && <View style={styles.flex1} />}
<View
style={[
styles.btnContainer,
isDesktopWeb && styles.btnContainerDesktop,
isTabletOrDesktop && styles.btnContainerDesktop,
]}>
<Button
testID="appPasswordBtn"
@ -77,7 +78,7 @@ export const AppPasswords = withAuthRequired(
<CenteredView
style={[
styles.container,
isDesktopWeb && styles.containerDesktop,
isTabletOrDesktop && styles.containerDesktop,
pal.view,
pal.border,
]}
@ -87,7 +88,7 @@ export const AppPasswords = withAuthRequired(
style={[
styles.scrollContainer,
pal.border,
!isDesktopWeb && styles.flex1,
!isTabletOrDesktop && styles.flex1,
]}>
{store.me.appPasswords.map((password, i) => (
<AppPassword
@ -97,7 +98,7 @@ export const AppPasswords = withAuthRequired(
createdAt={password.createdAt}
/>
))}
{isDesktopWeb && (
{isTabletOrDesktop && (
<View style={[styles.btnContainer, styles.btnContainerDesktop]}>
<Button
testID="appPasswordBtn"
@ -110,7 +111,7 @@ export const AppPasswords = withAuthRequired(
</View>
)}
</ScrollView>
{!isDesktopWeb && (
{!isTabletOrDesktop && (
<View style={styles.btnContainer}>
<Button
testID="appPasswordBtn"
@ -128,6 +129,7 @@ export const AppPasswords = withAuthRequired(
)
function AppPasswordsHeader() {
const {isTabletOrDesktop} = useWebMediaQueries()
const pal = usePalette('default')
return (
<>
@ -137,7 +139,7 @@ function AppPasswordsHeader() {
style={[
styles.description,
pal.text,
isDesktopWeb && styles.descriptionDesktop,
isTabletOrDesktop && styles.descriptionDesktop,
]}>
Use app passwords to login to other Bluesky clients without giving full
access to your account or password.
@ -207,11 +209,12 @@ function AppPassword({
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isDesktopWeb ? 0 : 100,
paddingBottom: 100,
},
containerDesktop: {
borderLeftWidth: 1,
borderRightWidth: 1,
paddingBottom: 0,
},
title: {
textAlign: 'center',

View file

@ -22,7 +22,7 @@ import {ViewHeader} from 'view/com/util/ViewHeader'
import {Button} from 'view/com/util/forms/Button'
import {Text} from 'view/com/util/text/Text'
import * as Toast from 'view/com/util/Toast'
import {isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {useSetTitle} from 'lib/hooks/useSetTitle'
import {shareUrl} from 'lib/sharing'
import {toShareUrl} from 'lib/strings/url-helpers'
@ -122,6 +122,7 @@ export const CustomFeedScreenInner = observer(
({route, feedOwnerDid}: Props & {feedOwnerDid: string}) => {
const store = useStores()
const pal = usePalette('default')
const {isTabletOrDesktop} = useWebMediaQueries()
const {track} = useAnalytics()
const {rkey, name: handleOrDid} = route.params
const uri = useMemo(
@ -357,7 +358,7 @@ export const CustomFeedScreenInner = observer(
)}
</Text>
)}
{isDesktopWeb && (
{isTabletOrDesktop && (
<View style={[styles.headerBtns, styles.headerBtnsDesktop]}>
<Button
type={currentFeed?.isSaved ? 'default' : 'inverted'}
@ -452,7 +453,14 @@ export const CustomFeedScreenInner = observer(
) : null}
</View>
</View>
<View style={[styles.fakeSelector, pal.border]}>
<View
style={[
styles.fakeSelector,
{
paddingHorizontal: isTabletOrDesktop ? 16 : 6,
},
pal.border,
]}>
<View
style={[styles.fakeSelectorItem, {borderColor: pal.colors.link}]}>
<Text type="md-medium" style={[pal.text]}>
@ -474,6 +482,7 @@ export const CustomFeedScreenInner = observer(
rkey,
isPinned,
onTogglePinned,
isTabletOrDesktop,
])
const renderEmptyState = React.useCallback(() => {
@ -486,7 +495,9 @@ export const CustomFeedScreenInner = observer(
return (
<View style={s.hContentRegion}>
<ViewHeader title="" renderButton={currentFeed && renderHeaderBtns} />
{!isTabletOrDesktop && (
<ViewHeader title="" renderButton={currentFeed && renderHeaderBtns} />
)}
<Feed
scrollElRef={scrollElRef}
feed={algoFeed}
@ -495,6 +506,7 @@ export const CustomFeedScreenInner = observer(
ListHeaderComponent={renderListHeaderComponent}
renderEmptyState={renderEmptyState}
extraData={[uri, isPinned]}
style={!isTabletOrDesktop ? {flex: 1} : undefined}
/>
{isScrolledDown ? (
<LoadLatestBtn
@ -550,7 +562,6 @@ const styles = StyleSheet.create({
},
fakeSelector: {
flexDirection: 'row',
paddingHorizontal: isDesktopWeb ? 16 : 6,
},
fakeSelectorItem: {
paddingHorizontal: 12,

View file

@ -10,8 +10,8 @@ import {FeedsDiscoveryModel} from 'state/models/discovery/feeds'
import {CenteredView, FlatList} from 'view/com/util/Views'
import {CustomFeed} from 'view/com/feeds/CustomFeed'
import {Text} from 'view/com/util/text/Text'
import {isDesktopWeb} from 'platform/detection'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {s} from 'lib/styles'
import {CustomFeedModel} from 'state/models/feeds/custom-feed'
import {HeaderWithInput} from 'view/com/search/HeaderWithInput'
@ -23,6 +23,7 @@ export const DiscoverFeedsScreen = withAuthRequired(
const store = useStores()
const pal = usePalette('default')
const feeds = React.useMemo(() => new FeedsDiscoveryModel(store), [store])
const {isTabletOrDesktop} = useWebMediaQueries()
// search stuff
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)
@ -74,7 +75,7 @@ export const DiscoverFeedsScreen = withAuthRequired(
<View style={styles.empty}>
<Text type="lg" style={pal.textLight}>
{feeds.isLoading
? isDesktopWeb
? isTabletOrDesktop
? 'Loading...'
: ''
: query
@ -100,23 +101,22 @@ export const DiscoverFeedsScreen = withAuthRequired(
return (
<CenteredView style={[styles.container, pal.view]}>
<View style={[isDesktopWeb && styles.containerDesktop, pal.border]}>
<View
style={[isTabletOrDesktop && styles.containerDesktop, pal.border]}>
<ViewHeader title="Discover Feeds" showOnDesktop />
<View style={{marginTop: isDesktopWeb ? 5 : 0, marginBottom: 4}}>
<HeaderWithInput
isInputFocused={isInputFocused}
query={query}
setIsInputFocused={setIsInputFocused}
onChangeQuery={onChangeQuery}
onPressClearQuery={onPressClearQuery}
onPressCancelSearch={onPressCancelSearch}
onSubmitQuery={onSubmitQuery}
showMenu={false}
/>
</View>
</View>
<HeaderWithInput
isInputFocused={isInputFocused}
query={query}
setIsInputFocused={setIsInputFocused}
onChangeQuery={onChangeQuery}
onPressClearQuery={onPressClearQuery}
onPressCancelSearch={onPressCancelSearch}
onSubmitQuery={onSubmitQuery}
showMenu={false}
/>
<FlatList
style={[!isDesktopWeb && s.flex1]}
style={[!isTabletOrDesktop && s.flex1]}
data={feeds.feeds}
keyExtractor={item => item.data.uri}
contentContainerStyle={styles.contentContainer}

View file

@ -12,22 +12,23 @@ import {NativeStackScreenProps, FeedsTabNavigatorParams} from 'lib/routes/types'
import {observer} from 'mobx-react-lite'
import {PostsMultiFeedModel} from 'state/models/feeds/multi-feed'
import {MultiFeed} from 'view/com/posts/MultiFeed'
import {isDesktopWeb} from 'platform/detection'
import {usePalette} from 'lib/hooks/usePalette'
import {useTimer} from 'lib/hooks/useTimer'
import {useStores} from 'state/index'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
import {ComposeIcon2, CogIcon} from 'lib/icons'
import {s} from 'lib/styles'
const LOAD_NEW_PROMPT_TIME = 60e3 // 60 seconds
const HEADER_OFFSET = isDesktopWeb ? 0 : 40
const MOBILE_HEADER_OFFSET = 40
type Props = NativeStackScreenProps<FeedsTabNavigatorParams, 'Feeds'>
export const FeedsScreen = withAuthRequired(
observer<Props>(({}: Props) => {
const pal = usePalette('default')
const store = useStores()
const {isMobile} = useWebMediaQueries()
const flatListRef = React.useRef<FlatList>(null)
const multifeed = React.useMemo<PostsMultiFeedModel>(
() => new PostsMultiFeedModel(store),
@ -105,14 +106,16 @@ export const FeedsScreen = withAuthRequired(
multifeed={multifeed}
onScroll={onMainScroll}
scrollEventThrottle={100}
headerOffset={HEADER_OFFSET}
/>
<ViewHeader
title="My Feeds"
canGoBack={false}
hideOnScroll
renderButton={renderHeaderBtn}
headerOffset={isMobile ? MOBILE_HEADER_OFFSET : undefined}
/>
{isMobile && (
<ViewHeader
title="My Feeds"
canGoBack={false}
hideOnScroll
renderButton={renderHeaderBtn}
/>
)}
{isScrolledDown || loadPromptVisible ? (
<LoadLatestBtn
onPress={onSoftReset}

View file

@ -19,14 +19,11 @@ import {useStores} from 'state/index'
import {s} from 'lib/styles'
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
import {useAnalytics} from 'lib/analytics/analytics'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {ComposeIcon2} from 'lib/icons'
import {isDesktopWeb, isMobileWebMediaQuery, isWeb} from 'platform/detection'
const HEADER_OFFSET_MOBILE = 78
const HEADER_OFFSET_DESKTOP = 50
const HEADER_OFFSET = isDesktopWeb
? HEADER_OFFSET_DESKTOP
: HEADER_OFFSET_MOBILE
const POLL_FREQ = 30e3 // 30sec
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
@ -158,10 +155,13 @@ const FeedPage = observer(
renderEmptyState?: () => JSX.Element
}) => {
const store = useStores()
const {isMobile} = useWebMediaQueries()
const [onMainScroll, isScrolledDown, resetMainScroll] =
useOnMainScroll(store)
const {screen, track} = useAnalytics()
const [headerOffset, setHeaderOffset] = React.useState(HEADER_OFFSET)
const [headerOffset, setHeaderOffset] = React.useState(
isMobile ? HEADER_OFFSET_MOBILE : HEADER_OFFSET_DESKTOP,
)
const scrollElRef = React.useRef<FlatList>(null)
const {appState} = useAppState({
onForeground: () => doPoll(true),
@ -206,15 +206,9 @@ const FeedPage = observer(
}, [isPageFocused, scrollToTop, feed])
// listens for resize events
const listenForResize = React.useCallback(() => {
// @ts-ignore we know window exists -prf
const isMobileWeb = global.window.matchMedia(
isMobileWebMediaQuery,
)?.matches
setHeaderOffset(
isMobileWeb ? HEADER_OFFSET_MOBILE : HEADER_OFFSET_DESKTOP,
)
}, [])
React.useEffect(() => {
setHeaderOffset(isMobile ? HEADER_OFFSET_MOBILE : HEADER_OFFSET_DESKTOP)
}, [isMobile])
// fires when page within screen is activated/deactivated
// - check for latest
@ -234,17 +228,10 @@ const FeedPage = observer(
feed.update()
}
if (isWeb) {
window.addEventListener('resize', listenForResize)
}
return () => {
clearInterval(pollInterval)
softResetSub.remove()
feedCleanup()
if (isWeb) {
isWeb && window.removeEventListener('resize', listenForResize)
}
}
}, [
store,
@ -254,7 +241,6 @@ const FeedPage = observer(
feed,
isPageFocused,
isScreenFocused,
listenForResize,
])
const onPressCompose = React.useCallback(() => {

View file

@ -16,7 +16,7 @@ import {Link} from '../com/util/Link'
import {Text} from '../com/util/text/Text'
import {usePalette} from 'lib/hooks/usePalette'
import {useAnalytics} from 'lib/analytics/analytics'
import {isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Moderation'>
export const ModerationScreen = withAuthRequired(
@ -24,6 +24,7 @@ export const ModerationScreen = withAuthRequired(
const pal = usePalette('default')
const store = useStores()
const {screen, track} = useAnalytics()
const {isTabletOrDesktop} = useWebMediaQueries()
useFocusEffect(
React.useCallback(() => {
@ -42,7 +43,7 @@ export const ModerationScreen = withAuthRequired(
style={[
s.hContentRegion,
pal.border,
isDesktopWeb ? styles.desktopContainer : pal.viewLight,
isTabletOrDesktop ? styles.desktopContainer : pal.viewLight,
]}
testID="moderationScreen">
<ViewHeader title="Moderation" showOnDesktop />

View file

@ -10,7 +10,7 @@ import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
import {Text} from '../com/util/text/Text'
import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette'
import {isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
@ -30,6 +30,7 @@ export const ModerationBlockedAccounts = withAuthRequired(
observer(({}: Props) => {
const pal = usePalette('default')
const store = useStores()
const {isTabletOrDesktop} = useWebMediaQueries()
const {screen} = useAnalytics()
const blockedAccounts = useMemo(
() => new BlockedAccountsModel(store),
@ -72,7 +73,7 @@ export const ModerationBlockedAccounts = withAuthRequired(
<CenteredView
style={[
styles.container,
isDesktopWeb && styles.containerDesktop,
isTabletOrDesktop && styles.containerDesktop,
pal.view,
pal.border,
]}
@ -83,14 +84,14 @@ export const ModerationBlockedAccounts = withAuthRequired(
style={[
styles.description,
pal.text,
isDesktopWeb && styles.descriptionDesktop,
isTabletOrDesktop && styles.descriptionDesktop,
]}>
Blocked accounts cannot reply in your threads, mention you, or
otherwise interact with you. You will not see their content and they
will be prevented from seeing yours.
</Text>
{!blockedAccounts.hasContent ? (
<View style={[pal.border, !isDesktopWeb && styles.flex1]}>
<View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
<View style={[styles.empty, pal.viewLight]}>
<Text type="lg" style={[pal.text, styles.emptyText]}>
You have not blocked any accounts yet. To block an account, go
@ -101,7 +102,7 @@ export const ModerationBlockedAccounts = withAuthRequired(
</View>
) : (
<FlatList
style={[!isDesktopWeb && styles.flex1]}
style={[!isTabletOrDesktop && styles.flex1]}
data={blockedAccounts.blocks}
keyExtractor={(item: ActorDefs.ProfileView) => item.did}
refreshControl={
@ -133,11 +134,12 @@ export const ModerationBlockedAccounts = withAuthRequired(
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isDesktopWeb ? 0 : 100,
paddingBottom: 100,
},
containerDesktop: {
borderLeftWidth: 1,
borderRightWidth: 1,
paddingBottom: 0,
},
title: {
textAlign: 'center',

View file

@ -15,9 +15,9 @@ import {ListsList} from 'view/com/lists/ListsList'
import {Button} from 'view/com/util/forms/Button'
import {NavigationProp} from 'lib/routes/types'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {CenteredView} from 'view/com/util/Views'
import {ViewHeader} from 'view/com/util/ViewHeader'
import {isDesktopWeb} from 'platform/detection'
type Props = NativeStackScreenProps<
CommonNavigatorParams,
@ -26,6 +26,7 @@ type Props = NativeStackScreenProps<
export const ModerationMuteListsScreen = withAuthRequired(({}: Props) => {
const pal = usePalette('default')
const store = useStores()
const {isTabletOrDesktop} = useWebMediaQueries()
const navigation = useNavigation<NavigationProp>()
const mutelists: ListsListModel = React.useMemo(
@ -89,7 +90,7 @@ export const ModerationMuteListsScreen = withAuthRequired(({}: Props) => {
styles.container,
pal.view,
pal.border,
isDesktopWeb && styles.containerDesktop,
isTabletOrDesktop && styles.containerDesktop,
]}
testID="moderationMutelistsScreen">
<ViewHeader
@ -99,7 +100,7 @@ export const ModerationMuteListsScreen = withAuthRequired(({}: Props) => {
/>
<ListsList
listsList={mutelists}
showAddBtns={isDesktopWeb}
showAddBtns={isTabletOrDesktop}
renderEmptyState={renderEmptyState}
onPressCreateNew={onPressNewMuteList}
/>
@ -110,11 +111,12 @@ export const ModerationMuteListsScreen = withAuthRequired(({}: Props) => {
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isDesktopWeb ? 0 : 100,
paddingBottom: 100,
},
containerDesktop: {
borderLeftWidth: 1,
borderRightWidth: 1,
paddingBottom: 0,
},
createBtn: {
width: 40,

View file

@ -10,7 +10,7 @@ import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
import {Text} from '../com/util/text/Text'
import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette'
import {isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
@ -30,6 +30,7 @@ export const ModerationMutedAccounts = withAuthRequired(
observer(({}: Props) => {
const pal = usePalette('default')
const store = useStores()
const {isTabletOrDesktop} = useWebMediaQueries()
const {screen} = useAnalytics()
const mutedAccounts = useMemo(() => new MutedAccountsModel(store), [store])
@ -69,7 +70,7 @@ export const ModerationMutedAccounts = withAuthRequired(
<CenteredView
style={[
styles.container,
isDesktopWeb && styles.containerDesktop,
isTabletOrDesktop && styles.containerDesktop,
pal.view,
pal.border,
]}
@ -80,13 +81,13 @@ export const ModerationMutedAccounts = withAuthRequired(
style={[
styles.description,
pal.text,
isDesktopWeb && styles.descriptionDesktop,
isTabletOrDesktop && styles.descriptionDesktop,
]}>
Muted accounts have their posts removed from your feed and from your
notifications. Mutes are completely private.
</Text>
{!mutedAccounts.hasContent ? (
<View style={[pal.border, !isDesktopWeb && styles.flex1]}>
<View style={[pal.border, !isTabletOrDesktop && styles.flex1]}>
<View style={[styles.empty, pal.viewLight]}>
<Text type="lg" style={[pal.text, styles.emptyText]}>
You have not muted any accounts yet. To mute an account, go to
@ -97,7 +98,7 @@ export const ModerationMutedAccounts = withAuthRequired(
</View>
) : (
<FlatList
style={[!isDesktopWeb && styles.flex1]}
style={[!isTabletOrDesktop && styles.flex1]}
data={mutedAccounts.mutes}
keyExtractor={item => item.did}
refreshControl={
@ -129,11 +130,12 @@ export const ModerationMutedAccounts = withAuthRequired(
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isDesktopWeb ? 0 : 100,
paddingBottom: 100,
},
containerDesktop: {
borderLeftWidth: 1,
borderRightWidth: 1,
paddingBottom: 0,
},
title: {
textAlign: 'center',

View file

@ -12,7 +12,7 @@ import {useStores} from 'state/index'
import {s} from 'lib/styles'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {clamp} from 'lodash'
import {isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
const SHELL_FOOTER_HEIGHT = 44
@ -26,6 +26,7 @@ export const PostThreadScreen = withAuthRequired(({route}: Props) => {
() => new PostThreadModel(store, {uri}),
[store, uri],
)
const {isMobile} = useWebMediaQueries()
useFocusEffect(
React.useCallback(() => {
@ -67,15 +68,15 @@ export const PostThreadScreen = withAuthRequired(({route}: Props) => {
return (
<View style={s.hContentRegion}>
<ViewHeader title="Post" />
<View style={s.hContentRegion}>
{isMobile && <ViewHeader title="Post" />}
<View style={s.flex1}>
<PostThreadComponent
uri={uri}
view={view}
onPressReply={onPressReply}
/>
</View>
{!isDesktopWeb && (
{isMobile && (
<View
style={[
styles.prompt,

View file

@ -6,7 +6,8 @@ import {Text} from '../com/util/text/Text'
import {useStores} from 'state/index'
import {s, colors} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {isWeb, isDesktopWeb} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {isWeb} from 'platform/detection'
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
import {ViewHeader} from 'view/com/util/ViewHeader'
@ -50,6 +51,7 @@ type Props = NativeStackScreenProps<
export const PreferencesHomeFeed = observer(({navigation}: Props) => {
const pal = usePalette('default')
const store = useStores()
const {isTabletOrDesktop} = useWebMediaQueries()
return (
<CenteredView
@ -58,10 +60,11 @@ export const PreferencesHomeFeed = observer(({navigation}: Props) => {
pal.view,
pal.border,
styles.container,
isDesktopWeb && styles.desktopContainer,
isTabletOrDesktop && styles.desktopContainer,
]}>
<ViewHeader title="Home Feed Preferences" showOnDesktop />
<View style={styles.titleSection}>
<View
style={[styles.titleSection, isTabletOrDesktop && {paddingTop: 20}]}>
<Text type="xl" style={[pal.textLight, styles.description]}>
Fine-tune the content you see on your home screen.
</Text>
@ -122,7 +125,12 @@ export const PreferencesHomeFeed = observer(({navigation}: Props) => {
</View>
</ScrollView>
<View style={[styles.btnContainer, pal.borderDark]}>
<View
style={[
styles.btnContainer,
!isTabletOrDesktop && {borderTopWidth: 1, paddingHorizontal: 20},
pal.borderDark,
]}>
<TouchableOpacity
testID="confirmBtn"
onPress={() => {
@ -130,7 +138,7 @@ export const PreferencesHomeFeed = observer(({navigation}: Props) => {
? navigation.goBack()
: navigation.navigate('Settings')
}}
style={[styles.btn, isDesktopWeb && styles.btnDesktop]}
style={[styles.btn, isTabletOrDesktop && styles.btnDesktop]}
accessibilityRole="button"
accessibilityLabel="Confirm"
accessibilityHint="">
@ -144,15 +152,15 @@ export const PreferencesHomeFeed = observer(({navigation}: Props) => {
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isDesktopWeb ? 40 : 90,
paddingBottom: 90,
},
desktopContainer: {
borderLeftWidth: 1,
borderRightWidth: 1,
paddingBottom: 40,
},
titleSection: {
paddingBottom: 30,
paddingTop: isDesktopWeb ? 20 : 0,
},
title: {
textAlign: 'center',
@ -184,7 +192,6 @@ const styles = StyleSheet.create({
},
btnContainer: {
paddingTop: 20,
borderTopWidth: isDesktopWeb ? 0 : 1,
},
dimmed: {
opacity: 0.3,

View file

@ -14,8 +14,8 @@ import {ListModel} from 'state/models/content/list'
import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette'
import {useSetTitle} from 'lib/hooks/useSetTitle'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {NavigationProp} from 'lib/routes/types'
import {isDesktopWeb} from 'platform/detection'
import {toShareUrl} from 'lib/strings/url-helpers'
import {shareUrl} from 'lib/sharing'
import {ListActions} from 'view/com/lists/ListActions'
@ -26,6 +26,7 @@ export const ProfileListScreen = withAuthRequired(
observer(({route}: Props) => {
const store = useStores()
const navigation = useNavigation<NavigationProp>()
const {isTabletOrDesktop} = useWebMediaQueries()
const pal = usePalette('default')
const {name, rkey} = route.params
@ -131,7 +132,7 @@ export const ProfileListScreen = withAuthRequired(
<CenteredView
style={[
styles.container,
isDesktopWeb && styles.containerDesktop,
isTabletOrDesktop && styles.containerDesktop,
pal.view,
pal.border,
]}
@ -155,10 +156,11 @@ export const ProfileListScreen = withAuthRequired(
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isDesktopWeb ? 0 : 100,
paddingBottom: 100,
},
containerDesktop: {
borderLeftWidth: 1,
borderRightWidth: 1,
paddingBottom: 0,
},
})

View file

@ -14,11 +14,12 @@ import {usePalette} from 'lib/hooks/usePalette'
import {CommonNavigatorParams} from 'lib/routes/types'
import {observer} from 'mobx-react-lite'
import {useStores} from 'state/index'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {ViewHeader} from 'view/com/util/ViewHeader'
import {CenteredView} from 'view/com/util/Views'
import {Text} from 'view/com/util/text/Text'
import {isDesktopWeb, isWeb} from 'platform/detection'
import {isWeb} from 'platform/detection'
import {s, colors} from 'lib/styles'
import DraggableFlatList, {
ShadowDecorator,
@ -37,6 +38,7 @@ export const SavedFeeds = withAuthRequired(
observer(({}: Props) => {
const pal = usePalette('default')
const store = useStores()
const {isMobile, isTabletOrDesktop} = useWebMediaQueries()
const {screen} = useAnalytics()
const savedFeeds = useMemo(() => store.me.savedFeeds, [store])
@ -53,7 +55,7 @@ export const SavedFeeds = withAuthRequired(
<View
style={[
pal.border,
!isDesktopWeb && s.flex1,
isMobile && s.flex1,
pal.viewLight,
styles.empty,
]}>
@ -62,7 +64,7 @@ export const SavedFeeds = withAuthRequired(
</Text>
</View>
)
}, [pal])
}, [pal, isMobile])
const renderListFooterComponent = useCallback(() => {
return (
@ -116,15 +118,11 @@ export const SavedFeeds = withAuthRequired(
style={[
s.hContentRegion,
pal.border,
isDesktopWeb && styles.desktopContainer,
isTabletOrDesktop && styles.desktopContainer,
]}>
<ViewHeader
title="Edit My Feeds"
showOnDesktop
showBorder={!isDesktopWeb}
/>
<ViewHeader title="Edit My Feeds" showOnDesktop showBorder />
<DraggableFlatList
containerStyle={[isDesktopWeb ? s.hContentRegion : s.flex1]}
containerStyle={[isTabletOrDesktop ? s.hContentRegion : s.flex1]}
data={savedFeeds.all}
keyExtractor={item => item.data.uri}
refreshing={savedFeeds.isRefreshing}

View file

@ -12,6 +12,7 @@ import {
SearchTabNavigatorParams,
} from 'lib/routes/types'
import {useStores} from 'state/index'
import {CenteredView} from 'view/com/util/Views'
import * as Mobile from './SearchMobile'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
@ -57,9 +58,9 @@ export const SearchScreen = withAuthRequired(
if (!isDesktop) {
return (
<View style={styles.scrollContainer}>
<CenteredView style={styles.scrollContainer}>
<Mobile.SearchScreen navigation={navigation} route={route} />
</View>
</CenteredView>
)
}

View file

@ -35,10 +35,10 @@ import {ToggleButton} from 'view/com/util/forms/ToggleButton'
import {SelectableBtn} from 'view/com/util/forms/SelectableBtn'
import {usePalette} from 'lib/hooks/usePalette'
import {useCustomPalette} from 'lib/hooks/useCustomPalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {AccountData} from 'state/models/session'
import {useAnalytics} from 'lib/analytics/analytics'
import {NavigationProp} from 'lib/routes/types'
import {isDesktopWeb} from 'platform/detection'
import {pluralize} from 'lib/strings/helpers'
import {formatCount} from 'view/com/util/numeric/format'
import Clipboard from '@react-native-clipboard/clipboard'
@ -58,6 +58,7 @@ export const SettingsScreen = withAuthRequired(
const pal = usePalette('default')
const store = useStores()
const navigation = useNavigation<NavigationProp>()
const {isMobile} = useWebMediaQueries()
const {screen, track} = useAnalytics()
const [isSwitching, setIsSwitching] = React.useState(false)
const [debugHeaderEnabled, toggleDebugHeader] = useDebugHeaderSetting(
@ -203,7 +204,7 @@ export const SettingsScreen = withAuthRequired(
<ViewHeader title="Settings" />
<ScrollView
style={[s.hContentRegion]}
contentContainerStyle={!isDesktopWeb && pal.viewLight}
contentContainerStyle={isMobile && pal.viewLight}
scrollIndicatorInsets={{right: 1}}>
<View style={styles.spacer20} />
{store.session.currentSession !== undefined ? (
@ -508,7 +509,7 @@ export const SettingsScreen = withAuthRequired(
System log
</Text>
</TouchableOpacity>
{isDesktopWeb || __DEV__ ? (
{__DEV__ ? (
<ToggleButton
type="default-light"
label="Experiment: Use AppView Proxy"