about summary refs log tree commit diff
path: root/src/view/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/screens')
-rw-r--r--src/view/screens/AppPasswords.tsx23
-rw-r--r--src/view/screens/CustomFeed.tsx21
-rw-r--r--src/view/screens/DiscoverFeeds.tsx32
-rw-r--r--src/view/screens/Feeds.tsx21
-rw-r--r--src/view/screens/Home.tsx30
-rw-r--r--src/view/screens/Moderation.tsx5
-rw-r--r--src/view/screens/ModerationBlockedAccounts.tsx14
-rw-r--r--src/view/screens/ModerationMuteLists.tsx10
-rw-r--r--src/view/screens/ModerationMutedAccounts.tsx14
-rw-r--r--src/view/screens/PostThread.tsx9
-rw-r--r--src/view/screens/PreferencesHomeFeed.tsx23
-rw-r--r--src/view/screens/ProfileList.tsx8
-rw-r--r--src/view/screens/SavedFeeds.tsx18
-rw-r--r--src/view/screens/Search.web.tsx5
-rw-r--r--src/view/screens/Settings.tsx7
15 files changed, 130 insertions, 110 deletions
diff --git a/src/view/screens/AppPasswords.tsx b/src/view/screens/AppPasswords.tsx
index 582bc0f9b..8fac86d34 100644
--- a/src/view/screens/AppPasswords.tsx
+++ b/src/view/screens/AppPasswords.tsx
@@ -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',
diff --git a/src/view/screens/CustomFeed.tsx b/src/view/screens/CustomFeed.tsx
index 01d499dad..f4e1b0eb7 100644
--- a/src/view/screens/CustomFeed.tsx
+++ b/src/view/screens/CustomFeed.tsx
@@ -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,
diff --git a/src/view/screens/DiscoverFeeds.tsx b/src/view/screens/DiscoverFeeds.tsx
index d4d4e5e6e..11f38c26a 100644
--- a/src/view/screens/DiscoverFeeds.tsx
+++ b/src/view/screens/DiscoverFeeds.tsx
@@ -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}
diff --git a/src/view/screens/Feeds.tsx b/src/view/screens/Feeds.tsx
index 7d45ce4c1..6e0706737 100644
--- a/src/view/screens/Feeds.tsx
+++ b/src/view/screens/Feeds.tsx
@@ -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}
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 4f1ebe039..795d813d1 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -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(() => {
diff --git a/src/view/screens/Moderation.tsx b/src/view/screens/Moderation.tsx
index 41df1244e..23a808feb 100644
--- a/src/view/screens/Moderation.tsx
+++ b/src/view/screens/Moderation.tsx
@@ -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 />
diff --git a/src/view/screens/ModerationBlockedAccounts.tsx b/src/view/screens/ModerationBlockedAccounts.tsx
index 959c6d9ca..10fa87080 100644
--- a/src/view/screens/ModerationBlockedAccounts.tsx
+++ b/src/view/screens/ModerationBlockedAccounts.tsx
@@ -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',
diff --git a/src/view/screens/ModerationMuteLists.tsx b/src/view/screens/ModerationMuteLists.tsx
index c2771290f..bc933c24e 100644
--- a/src/view/screens/ModerationMuteLists.tsx
+++ b/src/view/screens/ModerationMuteLists.tsx
@@ -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,
diff --git a/src/view/screens/ModerationMutedAccounts.tsx b/src/view/screens/ModerationMutedAccounts.tsx
index c638a55d7..eb822270a 100644
--- a/src/view/screens/ModerationMutedAccounts.tsx
+++ b/src/view/screens/ModerationMutedAccounts.tsx
@@ -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',
diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx
index 86b2d3027..a6aafa530 100644
--- a/src/view/screens/PostThread.tsx
+++ b/src/view/screens/PostThread.tsx
@@ -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,
diff --git a/src/view/screens/PreferencesHomeFeed.tsx b/src/view/screens/PreferencesHomeFeed.tsx
index b04f274f7..bd6dd8b39 100644
--- a/src/view/screens/PreferencesHomeFeed.tsx
+++ b/src/view/screens/PreferencesHomeFeed.tsx
@@ -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,
diff --git a/src/view/screens/ProfileList.tsx b/src/view/screens/ProfileList.tsx
index 3c50fdde0..e86a457b6 100644
--- a/src/view/screens/ProfileList.tsx
+++ b/src/view/screens/ProfileList.tsx
@@ -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,
   },
 })
diff --git a/src/view/screens/SavedFeeds.tsx b/src/view/screens/SavedFeeds.tsx
index aba61e7d9..5055ee76f 100644
--- a/src/view/screens/SavedFeeds.tsx
+++ b/src/view/screens/SavedFeeds.tsx
@@ -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}
diff --git a/src/view/screens/Search.web.tsx b/src/view/screens/Search.web.tsx
index 3218b4579..f325b1233 100644
--- a/src/view/screens/Search.web.tsx
+++ b/src/view/screens/Search.web.tsx
@@ -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>
       )
     }
 
diff --git a/src/view/screens/Settings.tsx b/src/view/screens/Settings.tsx
index 481d77086..a416bad45 100644
--- a/src/view/screens/Settings.tsx
+++ b/src/view/screens/Settings.tsx
@@ -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"