about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/alf/util/useColorModeTheme.ts20
-rw-r--r--src/view/com/composer/Composer.tsx15
-rw-r--r--src/view/com/composer/ComposerReplyTo.tsx3
-rw-r--r--src/view/shell/Composer.tsx38
4 files changed, 51 insertions, 25 deletions
diff --git a/src/alf/util/useColorModeTheme.ts b/src/alf/util/useColorModeTheme.ts
index 301c993dd..ce1558747 100644
--- a/src/alf/util/useColorModeTheme.ts
+++ b/src/alf/util/useColorModeTheme.ts
@@ -7,19 +7,21 @@ import {useThemePrefs} from 'state/shell'
 import {dark, dim, light, ThemeName} from '#/alf/themes'
 
 export function useColorModeTheme(): ThemeName {
-  const colorScheme = useColorScheme()
-  const {colorMode, darkTheme} = useThemePrefs()
+  const theme = useThemeName()
 
   React.useLayoutEffect(() => {
-    const theme = getThemeName(colorScheme, colorMode, darkTheme)
     updateDocument(theme)
     SystemUI.setBackgroundColorAsync(getBackgroundColor(theme))
-  }, [colorMode, colorScheme, darkTheme])
+  }, [theme])
+
+  return theme
+}
+
+export function useThemeName(): ThemeName {
+  const colorScheme = useColorScheme()
+  const {colorMode, darkTheme} = useThemePrefs()
 
-  return React.useMemo(
-    () => getThemeName(colorScheme, colorMode, darkTheme),
-    [colorScheme, colorMode, darkTheme],
-  )
+  return getThemeName(colorScheme, colorMode, darkTheme)
 }
 
 function getThemeName(
@@ -53,7 +55,7 @@ function updateDocument(theme: ThemeName) {
   }
 }
 
-function getBackgroundColor(theme: ThemeName): string {
+export function getBackgroundColor(theme: ThemeName): string {
   switch (theme) {
     case 'light':
       return light.atoms.bg.backgroundColor
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 4911adf2c..2618c51a3 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -54,7 +54,7 @@ import {useAgent, useSession} from '#/state/session'
 import {useComposerControls} from '#/state/shell/composer'
 import {useAnalytics} from 'lib/analytics/analytics'
 import * as apilib from 'lib/api/index'
-import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
+import {HITSLOP_10, MAX_GRAPHEME_LENGTH} from 'lib/constants'
 import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
@@ -165,9 +165,8 @@ export const ComposePost = observer(function ComposePost({
     () => ({
       paddingBottom:
         isAndroid || (isIOS && !isKeyboardVisible) ? insets.bottom : 0,
-      paddingTop: isMobile && isWeb ? 15 : insets.top,
     }),
-    [insets, isKeyboardVisible, isMobile],
+    [insets, isKeyboardVisible],
   )
 
   const hasScrolled = useSharedValue(0)
@@ -422,7 +421,8 @@ export const ComposePost = observer(function ComposePost({
               accessibilityLabel={_(msg`Cancel`)}
               accessibilityHint={_(
                 msg`Closes post composer and discards post draft`,
-              )}>
+              )}
+              hitSlop={HITSLOP_10}>
               <Text style={[pal.link, s.f18]}>
                 <Trans>Cancel</Trans>
               </Text>
@@ -622,10 +622,8 @@ const styles = StyleSheet.create({
   topbar: {
     flexDirection: 'row',
     alignItems: 'center',
-    marginTop: -10,
-    paddingHorizontal: 4,
     marginHorizontal: 16,
-    height: 44,
+    height: 54,
     gap: 4,
     borderBottomWidth: StyleSheet.hairlineWidth,
   },
@@ -633,7 +631,6 @@ const styles = StyleSheet.create({
     paddingTop: 10,
     paddingBottom: 10,
     height: 50,
-    marginTop: 0,
   },
   postBtn: {
     borderRadius: 20,
@@ -676,7 +673,7 @@ const styles = StyleSheet.create({
   },
   textInputLayout: {
     flexDirection: 'row',
-    paddingTop: 16,
+    paddingTop: 4,
   },
   textInputLayoutMobile: {
     flex: 1,
diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx
index 1bb4a5c21..902d60a46 100644
--- a/src/view/com/composer/ComposerReplyTo.tsx
+++ b/src/view/com/composer/ComposerReplyTo.tsx
@@ -223,8 +223,9 @@ const styles = StyleSheet.create({
     flexDirection: 'row',
     alignItems: 'flex-start',
     borderBottomWidth: StyleSheet.hairlineWidth,
-    paddingTop: 16,
+    paddingTop: 4,
     paddingBottom: 16,
+    marginBottom: 12,
   },
   replyToPost: {
     flex: 1,
diff --git a/src/view/shell/Composer.tsx b/src/view/shell/Composer.tsx
index 17348a30c..ce53ffc01 100644
--- a/src/view/shell/Composer.tsx
+++ b/src/view/shell/Composer.tsx
@@ -1,11 +1,15 @@
-import React from 'react'
+import React, {useLayoutEffect} from 'react'
 import {Modal, View} from 'react-native'
+import {StatusBar} from 'expo-status-bar'
+import * as SystemUI from 'expo-system-ui'
 import {observer} from 'mobx-react-lite'
 
+import {isIOS} from '#/platform/detection'
 import {Provider as LegacyModalProvider} from '#/state/modals'
-import {useComposerState} from 'state/shell/composer'
+import {useComposerState} from '#/state/shell/composer'
 import {ModalsContainer as LegacyModalsContainer} from '#/view/com/modals/Modal'
-import {useTheme} from '#/alf'
+import {atoms as a, useTheme} from '#/alf'
+import {getBackgroundColor, useThemeName} from '#/alf/util/useColorModeTheme'
 import {
   Outlet as PortalOutlet,
   Provider as PortalProvider,
@@ -19,15 +23,17 @@ export const Composer = observer(function ComposerImpl({}: {
   const state = useComposerState()
   const ref = useComposerCancelRef()
 
+  const open = !!state
+
   return (
     <Modal
       aria-modal
       accessibilityViewIsModal
-      visible={!!state}
-      presentationStyle="overFullScreen"
+      visible={open}
+      presentationStyle="formSheet"
       animationType="slide"
       onRequestClose={() => ref.current?.onPressCancel()}>
-      <View style={[t.atoms.bg, {flex: 1}]}>
+      <View style={[t.atoms.bg, a.flex_1]}>
         <LegacyModalProvider>
           <PortalProvider>
             <ComposePost
@@ -43,7 +49,27 @@ export const Composer = observer(function ComposerImpl({}: {
             <PortalOutlet />
           </PortalProvider>
         </LegacyModalProvider>
+        {isIOS && <IOSModalBackground active={open} />}
       </View>
     </Modal>
   )
 })
+
+// Generally, the backdrop of the app is the theme color, but when this is open
+// we want it to be black due to the modal being a form sheet.
+function IOSModalBackground({active}: {active: boolean}) {
+  const theme = useThemeName()
+
+  useLayoutEffect(() => {
+    SystemUI.setBackgroundColorAsync('black')
+
+    return () => {
+      SystemUI.setBackgroundColorAsync(getBackgroundColor(theme))
+    }
+  }, [theme])
+
+  // Set the status bar to light - however, only if the modal is active
+  // If we rely on this component being mounted to set this,
+  // there'll be a delay before it switches back to default.
+  return active ? <StatusBar style="light" animated /> : null
+}