about summary refs log tree commit diff
path: root/src/screens
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-10-14 22:09:47 +0300
committerGitHub <noreply@github.com>2024-10-14 22:09:47 +0300
commit2d88463453abfad1e9e45bbd6cdbcd5824a7e770 (patch)
tree40c411208b5e0c68d02814d5f525243c27cce306 /src/screens
parent0f40013963aaf4f3ac893ce58958ea30bc7a1efd (diff)
downloadvoidsky-2d88463453abfad1e9e45bbd6cdbcd5824a7e770.tar.zst
Remove top padding from shell, move down into individual screens (#5548)
Diffstat (limited to 'src/screens')
-rw-r--r--src/screens/E2E/SharedPreferencesTesterScreen.tsx199
-rw-r--r--src/screens/Hashtag.tsx31
-rw-r--r--src/screens/Messages/ChatList.tsx9
-rw-r--r--src/screens/Messages/Conversation.tsx13
-rw-r--r--src/screens/Messages/Settings.tsx175
-rw-r--r--src/screens/Moderation/index.tsx51
-rw-r--r--src/screens/Post/PostLikedBy.tsx18
-rw-r--r--src/screens/Post/PostQuotes.tsx18
-rw-r--r--src/screens/Post/PostRepostedBy.tsx18
-rw-r--r--src/screens/Profile/KnownFollowers.tsx28
-rw-r--r--src/screens/Profile/ProfileLabelerLikedBy.tsx6
-rw-r--r--src/screens/Settings/AppearanceSettings.tsx6
-rw-r--r--src/screens/StarterPack/StarterPackScreen.tsx27
-rw-r--r--src/screens/StarterPack/Wizard/index.tsx83
14 files changed, 361 insertions, 321 deletions
diff --git a/src/screens/E2E/SharedPreferencesTesterScreen.tsx b/src/screens/E2E/SharedPreferencesTesterScreen.tsx
index 06bf538ea..5a9e6cd22 100644
--- a/src/screens/E2E/SharedPreferencesTesterScreen.tsx
+++ b/src/screens/E2E/SharedPreferencesTesterScreen.tsx
@@ -1,9 +1,10 @@
 import React from 'react'
 import {View} from 'react-native'
 
-import {ScrollView} from 'view/com/util/Views'
+import {ScrollView} from '#/view/com/util/Views'
 import {atoms as a} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
+import * as Layout from '#/components/Layout'
 import {Text} from '#/components/Typography'
 import {SharedPrefs} from '../../../modules/expo-bluesky-swiss-army'
 
@@ -11,103 +12,105 @@ export function SharedPreferencesTesterScreen() {
   const [currentTestOutput, setCurrentTestOutput] = React.useState<string>('')
 
   return (
-    <ScrollView contentContainerStyle={{backgroundColor: 'red'}}>
-      <View style={[a.flex_1]}>
-        <View>
-          <Text testID="testOutput">{currentTestOutput}</Text>
+    <Layout.Screen>
+      <ScrollView contentContainerStyle={{backgroundColor: 'red'}}>
+        <View style={[a.flex_1]}>
+          <View>
+            <Text testID="testOutput">{currentTestOutput}</Text>
+          </View>
+          <View style={[a.flex_wrap]}>
+            <Button
+              label="btn"
+              testID="setStringBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerString')
+                SharedPrefs.setValue('testerString', 'Hello')
+                const str = SharedPrefs.getString('testerString')
+                console.log(JSON.stringify(str))
+                setCurrentTestOutput(`${str}`)
+              }}>
+              <ButtonText>Set String</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="removeStringBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerString')
+                const str = SharedPrefs.getString('testerString')
+                setCurrentTestOutput(`${str}`)
+              }}>
+              <ButtonText>Remove String</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="setBoolBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerBool')
+                SharedPrefs.setValue('testerBool', true)
+                const bool = SharedPrefs.getBool('testerBool')
+                setCurrentTestOutput(`${bool}`)
+              }}>
+              <ButtonText>Set Bool</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="setNumberBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeValue('testerNumber')
+                SharedPrefs.setValue('testerNumber', 123)
+                const num = SharedPrefs.getNumber('testerNumber')
+                setCurrentTestOutput(`${num}`)
+              }}>
+              <ButtonText>Set Number</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="addToSetBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeFromSet('testerSet', 'Hello!')
+                SharedPrefs.addToSet('testerSet', 'Hello!')
+                const contains = SharedPrefs.setContains('testerSet', 'Hello!')
+                setCurrentTestOutput(`${contains}`)
+              }}>
+              <ButtonText>Add to Set</ButtonText>
+            </Button>
+            <Button
+              label="btn"
+              testID="removeFromSetBtn"
+              style={[a.self_center]}
+              variant="solid"
+              color="primary"
+              size="small"
+              onPress={async () => {
+                SharedPrefs.removeFromSet('testerSet', 'Hello!')
+                const contains = SharedPrefs.setContains('testerSet', 'Hello!')
+                setCurrentTestOutput(`${contains}`)
+              }}>
+              <ButtonText>Remove from Set</ButtonText>
+            </Button>
+          </View>
         </View>
-        <View style={[a.flex_wrap]}>
-          <Button
-            label="btn"
-            testID="setStringBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerString')
-              SharedPrefs.setValue('testerString', 'Hello')
-              const str = SharedPrefs.getString('testerString')
-              console.log(JSON.stringify(str))
-              setCurrentTestOutput(`${str}`)
-            }}>
-            <ButtonText>Set String</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="removeStringBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerString')
-              const str = SharedPrefs.getString('testerString')
-              setCurrentTestOutput(`${str}`)
-            }}>
-            <ButtonText>Remove String</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="setBoolBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerBool')
-              SharedPrefs.setValue('testerBool', true)
-              const bool = SharedPrefs.getBool('testerBool')
-              setCurrentTestOutput(`${bool}`)
-            }}>
-            <ButtonText>Set Bool</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="setNumberBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeValue('testerNumber')
-              SharedPrefs.setValue('testerNumber', 123)
-              const num = SharedPrefs.getNumber('testerNumber')
-              setCurrentTestOutput(`${num}`)
-            }}>
-            <ButtonText>Set Number</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="addToSetBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeFromSet('testerSet', 'Hello!')
-              SharedPrefs.addToSet('testerSet', 'Hello!')
-              const contains = SharedPrefs.setContains('testerSet', 'Hello!')
-              setCurrentTestOutput(`${contains}`)
-            }}>
-            <ButtonText>Add to Set</ButtonText>
-          </Button>
-          <Button
-            label="btn"
-            testID="removeFromSetBtn"
-            style={[a.self_center]}
-            variant="solid"
-            color="primary"
-            size="small"
-            onPress={async () => {
-              SharedPrefs.removeFromSet('testerSet', 'Hello!')
-              const contains = SharedPrefs.setContains('testerSet', 'Hello!')
-              setCurrentTestOutput(`${contains}`)
-            }}>
-            <ButtonText>Remove from Set</ButtonText>
-          </Button>
-        </View>
-      </View>
-    </ScrollView>
+      </ScrollView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Hashtag.tsx b/src/screens/Hashtag.tsx
index 964cb0191..adf5f0080 100644
--- a/src/screens/Hashtag.tsx
+++ b/src/screens/Hashtag.tsx
@@ -6,23 +6,24 @@ import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 import {NativeStackScreenProps} from '@react-navigation/native-stack'
 
-import {HITSLOP_10} from 'lib/constants'
-import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
-import {CommonNavigatorParams} from 'lib/routes/types'
-import {shareUrl} from 'lib/sharing'
-import {cleanError} from 'lib/strings/errors'
-import {sanitizeHandle} from 'lib/strings/handles'
-import {enforceLen} from 'lib/strings/helpers'
-import {isNative, isWeb} from 'platform/detection'
-import {useSearchPostsQuery} from 'state/queries/search-posts'
-import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from 'state/shell'
+import {HITSLOP_10} from '#/lib/constants'
+import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
+import {CommonNavigatorParams} from '#/lib/routes/types'
+import {shareUrl} from '#/lib/sharing'
+import {cleanError} from '#/lib/strings/errors'
+import {sanitizeHandle} from '#/lib/strings/handles'
+import {enforceLen} from '#/lib/strings/helpers'
+import {isNative, isWeb} from '#/platform/detection'
+import {useSearchPostsQuery} from '#/state/queries/search-posts'
+import {useSetDrawerSwipeDisabled, useSetMinimalShellMode} from '#/state/shell'
 import {Pager} from '#/view/com/pager/Pager'
 import {TabBar} from '#/view/com/pager/TabBar'
+import {Post} from '#/view/com/post/Post'
+import {List} from '#/view/com/util/List'
+import {ViewHeader} from '#/view/com/util/ViewHeader'
 import {CenteredView} from '#/view/com/util/Views'
-import {Post} from 'view/com/post/Post'
-import {List} from 'view/com/util/List'
-import {ViewHeader} from 'view/com/util/ViewHeader'
 import {ArrowOutOfBox_Stroke2_Corner0_Rounded} from '#/components/icons/ArrowOutOfBox'
+import * as Layout from '#/components/Layout'
 import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
 
 const renderItem = ({item}: ListRenderItemInfo<PostView>) => {
@@ -108,7 +109,7 @@ export default function HashtagScreen({
   }, [_, fullTag, author, activeTab])
 
   return (
-    <>
+    <Layout.Screen>
       <CenteredView sideBorders={true}>
         <ViewHeader
           showOnDesktop
@@ -155,7 +156,7 @@ export default function HashtagScreen({
           <View key={i}>{section.component}</View>
         ))}
       </Pager>
-    </>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/screens/Messages/ChatList.tsx b/src/screens/Messages/ChatList.tsx
index 9912456e1..45b3bf14f 100644
--- a/src/screens/Messages/ChatList.tsx
+++ b/src/screens/Messages/ChatList.tsx
@@ -28,6 +28,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico
 import {Message_Stroke2_Corner0_Rounded as Message} from '#/components/icons/Message'
 import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
 import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider'
+import * as Layout from '#/components/Layout'
 import {Link} from '#/components/Link'
 import {ListFooter} from '#/components/Lists'
 import {Loader} from '#/components/Loader'
@@ -149,7 +150,7 @@ export function MessagesScreen({navigation, route}: Props) {
 
   if (conversations.length < 1) {
     return (
-      <View style={a.flex_1}>
+      <Layout.Screen>
         <CenteredView sideBorders={gtMobile} style={[a.h_full_vh]}>
           {gtMobile ? (
             <DesktopHeader
@@ -231,12 +232,12 @@ export function MessagesScreen({navigation, route}: Props) {
         {!isLoading && !isError && (
           <NewChat onNewChat={onNewChat} control={newChatControl} />
         )}
-      </View>
+      </Layout.Screen>
     )
   }
 
   return (
-    <View style={a.flex_1}>
+    <Layout.Screen testID="messagesScreen">
       {!gtMobile && (
         <ViewHeader
           title={_(msg`Messages`)}
@@ -276,7 +277,7 @@ export function MessagesScreen({navigation, route}: Props) {
         // @ts-ignore our .web version only -sfn
         desktopFixedHeight
       />
-    </View>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx
index 21fdfe0ea..651915738 100644
--- a/src/screens/Messages/Conversation.tsx
+++ b/src/screens/Messages/Conversation.tsx
@@ -18,10 +18,11 @@ import {useProfileQuery} from '#/state/queries/profile'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {CenteredView} from '#/view/com/util/Views'
 import {MessagesList} from '#/screens/Messages/components/MessagesList'
-import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
 import {MessagesListBlockedFooter} from '#/components/dms/MessagesListBlockedFooter'
 import {MessagesListHeader} from '#/components/dms/MessagesListHeader'
 import {Error} from '#/components/Error'
+import * as Layout from '#/components/Layout'
 import {Loader} from '#/components/Loader'
 
 type Props = NativeStackScreenProps<
@@ -64,9 +65,11 @@ export function MessagesConversationScreen({route}: Props) {
   )
 
   return (
-    <ConvoProvider key={convoId} convoId={convoId}>
-      <Inner />
-    </ConvoProvider>
+    <Layout.Screen testID="convoScreen" style={web([{minHeight: 0}, a.flex_1])}>
+      <ConvoProvider key={convoId} convoId={convoId}>
+        <Inner />
+      </ConvoProvider>
+    </Layout.Screen>
   )
 }
 
@@ -100,7 +103,7 @@ function Inner() {
 
   if (convoState.status === ConvoStatus.Error) {
     return (
-      <CenteredView style={a.flex_1} sideBorders>
+      <CenteredView style={[a.flex_1]} sideBorders>
         <MessagesListHeader />
         <Error
           title={_(msg`Something went wrong`)}
diff --git a/src/screens/Messages/Settings.tsx b/src/screens/Messages/Settings.tsx
index a7b55229f..93e3bc400 100644
--- a/src/screens/Messages/Settings.tsx
+++ b/src/screens/Messages/Settings.tsx
@@ -16,6 +16,7 @@ import {atoms as a} from '#/alf'
 import {Admonition} from '#/components/Admonition'
 import {Divider} from '#/components/Divider'
 import * as Toggle from '#/components/forms/Toggle'
+import * as Layout from '#/components/Layout'
 import {Text} from '#/components/Typography'
 import {useBackgroundNotificationPreferences} from '../../../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
 
@@ -55,91 +56,93 @@ export function MessagesSettingsScreen({}: Props) {
   )
 
   return (
-    <ScrollView stickyHeaderIndices={[0]}>
-      <ViewHeader title={_(msg`Chat Settings`)} showOnDesktop showBorder />
-      <View style={[a.p_lg, a.gap_md]}>
-        <Text style={[a.text_lg, a.font_bold]}>
-          <Trans>Allow new messages from</Trans>
-        </Text>
-        <Toggle.Group
-          label={_(msg`Allow new messages from`)}
-          type="radio"
-          values={[
-            (profile?.associated?.chat?.allowIncoming as AllowIncoming) ??
-              'following',
-          ]}
-          onChange={onSelectMessagesFrom}>
-          <View>
-            <Toggle.Item
-              name="all"
-              label={_(msg`Everyone`)}
-              style={[a.justify_between, a.py_sm]}>
-              <Toggle.LabelText>
-                <Trans>Everyone</Trans>
-              </Toggle.LabelText>
-              <Toggle.Radio />
-            </Toggle.Item>
-            <Toggle.Item
-              name="following"
-              label={_(msg`Users I follow`)}
-              style={[a.justify_between, a.py_sm]}>
-              <Toggle.LabelText>
-                <Trans>Users I follow</Trans>
-              </Toggle.LabelText>
-              <Toggle.Radio />
-            </Toggle.Item>
-            <Toggle.Item
-              name="none"
-              label={_(msg`No one`)}
-              style={[a.justify_between, a.py_sm]}>
-              <Toggle.LabelText>
-                <Trans>No one</Trans>
-              </Toggle.LabelText>
-              <Toggle.Radio />
-            </Toggle.Item>
-          </View>
-        </Toggle.Group>
-        <Admonition type="tip">
-          <Trans>
-            You can continue ongoing conversations regardless of which setting
-            you choose.
-          </Trans>
-        </Admonition>
-        {isNative && (
-          <>
-            <Divider style={a.my_md} />
-            <Text style={[a.text_lg, a.font_bold]}>
-              <Trans>Notification Sounds</Trans>
-            </Text>
-            <Toggle.Group
-              label={_(msg`Notification sounds`)}
-              type="radio"
-              values={[preferences.playSoundChat ? 'enabled' : 'disabled']}
-              onChange={onSelectSoundSetting}>
-              <View>
-                <Toggle.Item
-                  name="enabled"
-                  label={_(msg`Enabled`)}
-                  style={[a.justify_between, a.py_sm]}>
-                  <Toggle.LabelText>
-                    <Trans>Enabled</Trans>
-                  </Toggle.LabelText>
-                  <Toggle.Radio />
-                </Toggle.Item>
-                <Toggle.Item
-                  name="disabled"
-                  label={_(msg`Disabled`)}
-                  style={[a.justify_between, a.py_sm]}>
-                  <Toggle.LabelText>
-                    <Trans>Disabled</Trans>
-                  </Toggle.LabelText>
-                  <Toggle.Radio />
-                </Toggle.Item>
-              </View>
-            </Toggle.Group>
-          </>
-        )}
-      </View>
-    </ScrollView>
+    <Layout.Screen testID="messagesSettingsScreen">
+      <ScrollView stickyHeaderIndices={[0]}>
+        <ViewHeader title={_(msg`Chat Settings`)} showOnDesktop showBorder />
+        <View style={[a.p_lg, a.gap_md]}>
+          <Text style={[a.text_lg, a.font_bold]}>
+            <Trans>Allow new messages from</Trans>
+          </Text>
+          <Toggle.Group
+            label={_(msg`Allow new messages from`)}
+            type="radio"
+            values={[
+              (profile?.associated?.chat?.allowIncoming as AllowIncoming) ??
+                'following',
+            ]}
+            onChange={onSelectMessagesFrom}>
+            <View>
+              <Toggle.Item
+                name="all"
+                label={_(msg`Everyone`)}
+                style={[a.justify_between, a.py_sm]}>
+                <Toggle.LabelText>
+                  <Trans>Everyone</Trans>
+                </Toggle.LabelText>
+                <Toggle.Radio />
+              </Toggle.Item>
+              <Toggle.Item
+                name="following"
+                label={_(msg`Users I follow`)}
+                style={[a.justify_between, a.py_sm]}>
+                <Toggle.LabelText>
+                  <Trans>Users I follow</Trans>
+                </Toggle.LabelText>
+                <Toggle.Radio />
+              </Toggle.Item>
+              <Toggle.Item
+                name="none"
+                label={_(msg`No one`)}
+                style={[a.justify_between, a.py_sm]}>
+                <Toggle.LabelText>
+                  <Trans>No one</Trans>
+                </Toggle.LabelText>
+                <Toggle.Radio />
+              </Toggle.Item>
+            </View>
+          </Toggle.Group>
+          <Admonition type="tip">
+            <Trans>
+              You can continue ongoing conversations regardless of which setting
+              you choose.
+            </Trans>
+          </Admonition>
+          {isNative && (
+            <>
+              <Divider style={a.my_md} />
+              <Text style={[a.text_lg, a.font_bold]}>
+                <Trans>Notification Sounds</Trans>
+              </Text>
+              <Toggle.Group
+                label={_(msg`Notification sounds`)}
+                type="radio"
+                values={[preferences.playSoundChat ? 'enabled' : 'disabled']}
+                onChange={onSelectSoundSetting}>
+                <View>
+                  <Toggle.Item
+                    name="enabled"
+                    label={_(msg`Enabled`)}
+                    style={[a.justify_between, a.py_sm]}>
+                    <Toggle.LabelText>
+                      <Trans>Enabled</Trans>
+                    </Toggle.LabelText>
+                    <Toggle.Radio />
+                  </Toggle.Item>
+                  <Toggle.Item
+                    name="disabled"
+                    label={_(msg`Disabled`)}
+                    style={[a.justify_between, a.py_sm]}>
+                    <Toggle.LabelText>
+                      <Trans>Disabled</Trans>
+                    </Toggle.LabelText>
+                    <Toggle.Radio />
+                  </Toggle.Item>
+                </View>
+              </Toggle.Group>
+            </>
+          )}
+        </View>
+      </ScrollView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx
index 070b87950..222774e05 100644
--- a/src/screens/Moderation/index.tsx
+++ b/src/screens/Moderation/index.tsx
@@ -41,6 +41,7 @@ import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filte
 import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group'
 import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person'
 import * as LabelingService from '#/components/LabelingServiceCard'
+import * as Layout from '#/components/Layout'
 import {InlineLinkText, Link} from '#/components/Link'
 import {Loader} from '#/components/Loader'
 import {GlobalLabelPreference} from '#/components/moderation/LabelPreference'
@@ -94,31 +95,33 @@ export function ModerationScreen(
   const error = preferencesError
 
   return (
-    <CenteredView
-      testID="moderationScreen"
-      style={[
-        t.atoms.border_contrast_low,
-        t.atoms.bg,
-        {minHeight: height},
-        ...(gtMobile ? [a.border_l, a.border_r] : []),
-      ]}>
-      <ViewHeader title={_(msg`Moderation`)} showOnDesktop />
+    <Layout.Screen testID="moderationScreen">
+      <CenteredView
+        testID="moderationScreen"
+        style={[
+          t.atoms.border_contrast_low,
+          t.atoms.bg,
+          {minHeight: height},
+          ...(gtMobile ? [a.border_l, a.border_r] : []),
+        ]}>
+        <ViewHeader title={_(msg`Moderation`)} showOnDesktop />
 
-      {isLoading ? (
-        <View style={[a.w_full, a.align_center, a.pt_2xl]}>
-          <Loader size="xl" fill={t.atoms.text.color} />
-        </View>
-      ) : error || !preferences ? (
-        <ErrorState
-          error={
-            preferencesError?.toString() ||
-            _(msg`Something went wrong, please try again.`)
-          }
-        />
-      ) : (
-        <ModerationScreenInner preferences={preferences} />
-      )}
-    </CenteredView>
+        {isLoading ? (
+          <View style={[a.w_full, a.align_center, a.pt_2xl]}>
+            <Loader size="xl" fill={t.atoms.text.color} />
+          </View>
+        ) : error || !preferences ? (
+          <ErrorState
+            error={
+              preferencesError?.toString() ||
+              _(msg`Something went wrong, please try again.`)
+            }
+          />
+        ) : (
+          <ModerationScreenInner preferences={preferences} />
+        )}
+      </CenteredView>
+    </Layout.Screen>
   )
 }
 
diff --git a/src/screens/Post/PostLikedBy.tsx b/src/screens/Post/PostLikedBy.tsx
index ea522488c..6fc485f34 100644
--- a/src/screens/Post/PostLikedBy.tsx
+++ b/src/screens/Post/PostLikedBy.tsx
@@ -5,12 +5,12 @@ import {useFocusEffect} from '@react-navigation/native'
 
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {isWeb} from 'platform/detection'
 import {PostLikedBy as PostLikedByComponent} from '#/view/com/post-thread/PostLikedBy'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostLikedBy'>
@@ -27,10 +27,12 @@ export const PostLikedByScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Liked By`)} />
-      <ViewHeader title={_(msg`Liked By`)} showBorder={!isWeb} />
-      <PostLikedByComponent uri={uri} />
-    </CenteredView>
+    <Layout.Screen>
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Liked By`)} />
+        <ViewHeader title={_(msg`Liked By`)} showBorder={!isWeb} />
+        <PostLikedByComponent uri={uri} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Post/PostQuotes.tsx b/src/screens/Post/PostQuotes.tsx
index 0d59418f1..71dd8ad8d 100644
--- a/src/screens/Post/PostQuotes.tsx
+++ b/src/screens/Post/PostQuotes.tsx
@@ -5,12 +5,12 @@ import {useFocusEffect} from '@react-navigation/native'
 
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {isWeb} from 'platform/detection'
 import {PostQuotes as PostQuotesComponent} from '#/view/com/post-thread/PostQuotes'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostQuotes'>
@@ -27,10 +27,12 @@ export const PostQuotesScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Quotes`)} />
-      <ViewHeader title={_(msg`Quotes`)} showBorder={!isWeb} />
-      <PostQuotesComponent uri={uri} />
-    </CenteredView>
+    <Layout.Screen>
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Quotes`)} />
+        <ViewHeader title={_(msg`Quotes`)} showBorder={!isWeb} />
+        <PostQuotesComponent uri={uri} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Post/PostRepostedBy.tsx b/src/screens/Post/PostRepostedBy.tsx
index f8c058ff7..c1e8b2987 100644
--- a/src/screens/Post/PostRepostedBy.tsx
+++ b/src/screens/Post/PostRepostedBy.tsx
@@ -5,12 +5,12 @@ import {useFocusEffect} from '@react-navigation/native'
 
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
+import {isWeb} from '#/platform/detection'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {isWeb} from 'platform/detection'
 import {PostRepostedBy as PostRepostedByComponent} from '#/view/com/post-thread/PostRepostedBy'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
-import {CenteredView} from 'view/com/util/Views'
-import {atoms as a} from '#/alf'
+import {CenteredView} from '#/view/com/util/Views'
+import * as Layout from '#/components/Layout'
 import {ListHeaderDesktop} from '#/components/Lists'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostRepostedBy'>
@@ -27,10 +27,12 @@ export const PostRepostedByScreen = ({route}: Props) => {
   )
 
   return (
-    <CenteredView style={a.util_screen_outer} sideBorders={true}>
-      <ListHeaderDesktop title={_(msg`Reposted By`)} />
-      <ViewHeader title={_(msg`Reposted By`)} showBorder={!isWeb} />
-      <PostRepostedByComponent uri={uri} />
-    </CenteredView>
+    <Layout.Screen>
+      <CenteredView sideBorders={true}>
+        <ListHeaderDesktop title={_(msg`Reposted By`)} />
+        <ViewHeader title={_(msg`Reposted By`)} showBorder={!isWeb} />
+        <PostRepostedByComponent uri={uri} />
+      </CenteredView>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Profile/KnownFollowers.tsx b/src/screens/Profile/KnownFollowers.tsx
index 5cb45a11e..7e396c350 100644
--- a/src/screens/Profile/KnownFollowers.tsx
+++ b/src/screens/Profile/KnownFollowers.tsx
@@ -1,20 +1,20 @@
 import React from 'react'
-import {View} from 'react-native'
 import {AppBskyActorDefs} from '@atproto/api'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
 
+import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
+import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {cleanError} from '#/lib/strings/errors'
 import {logger} from '#/logger'
 import {useProfileKnownFollowersQuery} from '#/state/queries/known-followers'
 import {useResolveDidQuery} from '#/state/queries/resolve-uri'
 import {useSetMinimalShellMode} from '#/state/shell'
-import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
-import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
 import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard'
 import {List} from '#/view/com/util/List'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 import {
   ListFooter,
   ListHeaderDesktop,
@@ -92,19 +92,21 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => {
 
   if (followers.length < 1) {
     return (
-      <ListMaybePlaceholder
-        isLoading={isDidLoading || isFollowersLoading}
-        isError={isError}
-        emptyType="results"
-        emptyMessage={_(msg`You don't follow any users who follow @${name}.`)}
-        errorMessage={cleanError(resolveError || error)}
-        onRetry={isError ? refetch : undefined}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={isDidLoading || isFollowersLoading}
+          isError={isError}
+          emptyType="results"
+          emptyMessage={_(msg`You don't follow any users who follow @${name}.`)}
+          errorMessage={cleanError(resolveError || error)}
+          onRetry={isError ? refetch : undefined}
+        />
+      </Layout.Screen>
     )
   }
 
   return (
-    <View style={{flex: 1}}>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Followers you know`)} />
       <List
         data={followers}
@@ -129,6 +131,6 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => {
         initialNumToRender={initialNumToRender}
         windowSize={11}
       />
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Profile/ProfileLabelerLikedBy.tsx b/src/screens/Profile/ProfileLabelerLikedBy.tsx
index 8650ac2e6..ccc270084 100644
--- a/src/screens/Profile/ProfileLabelerLikedBy.tsx
+++ b/src/screens/Profile/ProfileLabelerLikedBy.tsx
@@ -1,5 +1,4 @@
 import React from 'react'
-import {View} from 'react-native'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useFocusEffect} from '@react-navigation/native'
@@ -8,6 +7,7 @@ import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {ViewHeader} from '#/view/com/util/ViewHeader'
+import * as Layout from '#/components/Layout'
 import {LikedByList} from '#/components/LikedByList'
 
 export function ProfileLabelerLikedByScreen({
@@ -25,9 +25,9 @@ export function ProfileLabelerLikedByScreen({
   )
 
   return (
-    <View style={{flex: 1}}>
+    <Layout.Screen>
       <ViewHeader title={_(msg`Liked By`)} />
       <LikedByList uri={uri} />
-    </View>
+    </Layout.Screen>
   )
 }
diff --git a/src/screens/Settings/AppearanceSettings.tsx b/src/screens/Settings/AppearanceSettings.tsx
index 69e04f4af..c317c930f 100644
--- a/src/screens/Settings/AppearanceSettings.tsx
+++ b/src/screens/Settings/AppearanceSettings.tsx
@@ -10,7 +10,6 @@ import {useLingui} from '@lingui/react'
 
 import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
 import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
-import {s} from '#/lib/styles'
 import {useSetThemePrefs, useThemePrefs} from '#/state/shell'
 import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
 import {ScrollView} from '#/view/com/util/Views'
@@ -21,6 +20,7 @@ import {Moon_Stroke2_Corner0_Rounded as MoonIcon} from '#/components/icons/Moon'
 import {Phone_Stroke2_Corner0_Rounded as PhoneIcon} from '#/components/icons/Phone'
 import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/TextSize'
 import {TitleCase_Stroke2_Corner0_Rounded as Aa} from '#/components/icons/TitleCase'
+import * as Layout from '#/components/Layout'
 import {Text} from '#/components/Typography'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppearanceSettings'>
@@ -76,7 +76,7 @@ export function AppearanceSettingsScreen({}: Props) {
 
   return (
     <LayoutAnimationConfig skipExiting skipEntering>
-      <View testID="preferencesThreadsScreen" style={s.hContentRegion}>
+      <Layout.Screen testID="preferencesThreadsScreen">
         <ScrollView
           // @ts-ignore web only -prf
           dataSet={{'stable-gutters': 1}}
@@ -180,7 +180,7 @@ export function AppearanceSettingsScreen({}: Props) {
             </View>
           </View>
         </ScrollView>
-      </View>
+      </Layout.Screen>
     </LayoutAnimationConfig>
   )
 }
diff --git a/src/screens/StarterPack/StarterPackScreen.tsx b/src/screens/StarterPack/StarterPackScreen.tsx
index 68803ac00..4baec9ec1 100644
--- a/src/screens/StarterPack/StarterPackScreen.tsx
+++ b/src/screens/StarterPack/StarterPackScreen.tsx
@@ -53,6 +53,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico
 import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
 import {Pencil_Stroke2_Corner0_Rounded as Pencil} from '#/components/icons/Pencil'
 import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
+import * as Layout from '#/components/Layout'
 import {ListMaybePlaceholder} from '#/components/Lists'
 import {Loader} from '#/components/Loader'
 import * as Menu from '#/components/Menu'
@@ -76,7 +77,11 @@ type StarterPackScreenShortProps = NativeStackScreenProps<
 >
 
 export function StarterPackScreen({route}: StarterPackScreeProps) {
-  return <StarterPackScreenInner routeParams={route.params} />
+  return (
+    <Layout.Screen>
+      <StarterPackScreenInner routeParams={route.params} />
+    </Layout.Screen>
+  )
 }
 
 export function StarterPackScreenShort({route}: StarterPackScreenShortProps) {
@@ -91,15 +96,21 @@ export function StarterPackScreenShort({route}: StarterPackScreenShortProps) {
 
   if (isLoading || isError || !resolvedStarterPack) {
     return (
-      <ListMaybePlaceholder
-        isLoading={isLoading}
-        isError={isError}
-        errorMessage={_(msg`That starter pack could not be found.`)}
-        emptyMessage={_(msg`That starter pack could not be found.`)}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={isLoading}
+          isError={isError}
+          errorMessage={_(msg`That starter pack could not be found.`)}
+          emptyMessage={_(msg`That starter pack could not be found.`)}
+        />
+      </Layout.Screen>
     )
   }
-  return <StarterPackScreenInner routeParams={resolvedStarterPack} />
+  return (
+    <Layout.Screen>
+      <StarterPackScreenInner routeParams={resolvedStarterPack} />
+    </Layout.Screen>
+  )
 }
 
 export function StarterPackScreenInner({
diff --git a/src/screens/StarterPack/Wizard/index.tsx b/src/screens/StarterPack/Wizard/index.tsx
index 29ef44ee0..f8d503274 100644
--- a/src/screens/StarterPack/Wizard/index.tsx
+++ b/src/screens/StarterPack/Wizard/index.tsx
@@ -19,32 +19,32 @@ import {useLingui} from '@lingui/react'
 import {useFocusEffect, useNavigation} from '@react-navigation/native'
 import {NativeStackScreenProps} from '@react-navigation/native-stack'
 
-import {logger} from '#/logger'
-import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from 'lib/constants'
-import {createSanitizedDisplayName} from 'lib/moderation/create-sanitized-display-name'
-import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
-import {logEvent} from 'lib/statsig/statsig'
-import {sanitizeDisplayName} from 'lib/strings/display-names'
-import {sanitizeHandle} from 'lib/strings/handles'
-import {enforceLen} from 'lib/strings/helpers'
+import {HITSLOP_10, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
+import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
+import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
+import {logEvent} from '#/lib/statsig/statsig'
+import {sanitizeDisplayName} from '#/lib/strings/display-names'
+import {sanitizeHandle} from '#/lib/strings/handles'
+import {enforceLen} from '#/lib/strings/helpers'
 import {
   getStarterPackOgCard,
   parseStarterPackUri,
-} from 'lib/strings/starter-pack'
-import {isAndroid, isNative, isWeb} from 'platform/detection'
-import {useModerationOpts} from 'state/preferences/moderation-opts'
-import {useAllListMembersQuery} from 'state/queries/list-members'
-import {useProfileQuery} from 'state/queries/profile'
+} from '#/lib/strings/starter-pack'
+import {logger} from '#/logger'
+import {isAndroid, isNative, isWeb} from '#/platform/detection'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
+import {useAllListMembersQuery} from '#/state/queries/list-members'
+import {useProfileQuery} from '#/state/queries/profile'
 import {
   useCreateStarterPackMutation,
   useEditStarterPackMutation,
   useStarterPackQuery,
-} from 'state/queries/starter-packs'
-import {useSession} from 'state/session'
-import {useSetMinimalShellMode} from 'state/shell'
+} from '#/state/queries/starter-packs'
+import {useSession} from '#/state/session'
+import {useSetMinimalShellMode} from '#/state/shell'
 import * as Toast from '#/view/com/util/Toast'
-import {UserAvatar} from 'view/com/util/UserAvatar'
-import {CenteredView} from 'view/com/util/Views'
+import {UserAvatar} from '#/view/com/util/UserAvatar'
+import {CenteredView} from '#/view/com/util/Views'
 import {useWizardState, WizardStep} from '#/screens/StarterPack/Wizard/State'
 import {StepDetails} from '#/screens/StarterPack/Wizard/StepDetails'
 import {StepFeeds} from '#/screens/StarterPack/Wizard/StepFeeds'
@@ -52,6 +52,7 @@ import {StepProfiles} from '#/screens/StarterPack/Wizard/StepProfiles'
 import {atoms as a, useTheme} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
 import {useDialogControl} from '#/components/Dialog'
+import * as Layout from '#/components/Layout'
 import {ListMaybePlaceholder} from '#/components/Lists'
 import {Loader} from '#/components/Loader'
 import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog'
@@ -97,33 +98,39 @@ export function Wizard({
 
   if (!isReady) {
     return (
-      <ListMaybePlaceholder
-        isLoading={
-          isLoadingStarterPack || isLoadingProfiles || isLoadingProfile
-        }
-        isError={isErrorStarterPack || isErrorProfiles || isErrorProfile}
-        errorMessage={_(msg`That starter pack could not be found.`)}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={
+            isLoadingStarterPack || isLoadingProfiles || isLoadingProfile
+          }
+          isError={isErrorStarterPack || isErrorProfiles || isErrorProfile}
+          errorMessage={_(msg`That starter pack could not be found.`)}
+        />
+      </Layout.Screen>
     )
   } else if (isEdit && starterPack?.creator.did !== currentAccount?.did) {
     return (
-      <ListMaybePlaceholder
-        isLoading={false}
-        isError={true}
-        errorMessage={_(msg`That starter pack could not be found.`)}
-      />
+      <Layout.Screen>
+        <ListMaybePlaceholder
+          isLoading={false}
+          isError={true}
+          errorMessage={_(msg`That starter pack could not be found.`)}
+        />
+      </Layout.Screen>
     )
   }
 
   return (
-    <Provider starterPack={starterPack} listItems={listItems}>
-      <WizardInner
-        currentStarterPack={starterPack}
-        currentListItems={listItems}
-        profile={profile}
-        moderationOpts={moderationOpts}
-      />
-    </Provider>
+    <Layout.Screen>
+      <Provider starterPack={starterPack} listItems={listItems}>
+        <WizardInner
+          currentStarterPack={starterPack}
+          currentListItems={listItems}
+          profile={profile}
+          moderationOpts={moderationOpts}
+        />
+      </Provider>
+    </Layout.Screen>
   )
 }