about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-04-24 16:36:05 -0500
committerGitHub <noreply@github.com>2023-04-24 16:36:05 -0500
commitda8af38dcc23ea33c686714be2ce5f0bf0e65798 (patch)
tree78156a3b5803ccda6883e9e694ca79ccfdc40473 /src
parent9d8600c21387999f8621274c553d5385be0c92c7 (diff)
downloadvoidsky-da8af38dcc23ea33c686714be2ce5f0bf0e65798.tar.zst
Android & visual fixes: color themes, repost icon, navigation, back handler, etc (#519)
* Switch android to use slide left/right animations on navigation

* Bump the repost icon down by a pixel

* Tune theme colors for contrast and darker bg on darkmode

* Move back handler to a point in the init flow that leads to more consistent capture of events

* Fix image share flow on android

* Fix lint

* Add todo about sharing not available

* Drop the android slide animation because it's too slow

* Fix 'flashes of white' in dark mode android
Diffstat (limited to 'src')
-rw-r--r--src/App.native.tsx2
-rw-r--r--src/Navigation.tsx7
-rw-r--r--src/lib/icons.tsx2
-rw-r--r--src/lib/media/manip.ts25
-rw-r--r--src/lib/routes/back-handler.ts9
-rw-r--r--src/lib/themes.ts6
-rw-r--r--src/view/com/composer/Composer.tsx6
-rw-r--r--src/view/com/modals/Modal.web.tsx2
-rw-r--r--src/view/com/util/forms/DropdownButton.tsx6
-rw-r--r--src/view/screens/Settings.tsx10
-rw-r--r--src/view/shell/Composer.web.tsx3
-rw-r--r--src/view/shell/index.tsx6
12 files changed, 48 insertions, 36 deletions
diff --git a/src/App.native.tsx b/src/App.native.tsx
index f4f787a01..e0e030cbc 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -13,7 +13,6 @@ import {RootStoreModel, setupState, RootStoreProvider} from './state'
 import {Shell} from './view/shell'
 import * as notifee from 'lib/notifee'
 import * as analytics from 'lib/analytics'
-import * as backHandler from 'lib/routes/back-handler'
 import * as Toast from './view/com/util/Toast'
 import {handleLink} from './Navigation'
 
@@ -29,7 +28,6 @@ const App = observer(() => {
       setRootStore(store)
       analytics.init(store)
       notifee.init(store)
-      backHandler.init(store)
       SplashScreen.hideAsync()
       Linking.getInitialURL().then((url: string | null) => {
         if (url) {
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
index 186432c8c..d5ffb1539 100644
--- a/src/Navigation.tsx
+++ b/src/Navigation.tsx
@@ -6,6 +6,8 @@ import {
   createNavigationContainerRef,
   CommonActions,
   StackActions,
+  DefaultTheme,
+  DarkTheme,
 } from '@react-navigation/native'
 import {createNativeStackNavigator} from '@react-navigation/native-stack'
 import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'
@@ -256,8 +258,9 @@ const LINKING = {
 }
 
 function RoutesContainer({children}: React.PropsWithChildren<{}>) {
+  const theme = useColorSchemeStyle(DefaultTheme, DarkTheme)
   return (
-    <NavigationContainer ref={navigationRef} linking={LINKING}>
+    <NavigationContainer ref={navigationRef} linking={LINKING} theme={theme}>
       {children}
     </NavigationContainer>
   )
@@ -334,7 +337,7 @@ const styles = StyleSheet.create({
     backgroundColor: colors.black,
   },
   bgLight: {
-    backgroundColor: colors.gray1,
+    backgroundColor: colors.white,
   },
 })
 
diff --git a/src/lib/icons.tsx b/src/lib/icons.tsx
index 300c13b0d..4cb491e46 100644
--- a/src/lib/icons.tsx
+++ b/src/lib/icons.tsx
@@ -431,7 +431,7 @@ export function RepostIcon({
         strokeWidth={strokeWidth}
         strokeLinejoin="round"
         fill="none"
-        d="M 14.437 17.081 L 5.475 17.095 C 4.7 17.095 4.072 16.467 4.072 15.692 L 4.082 5.65 L 1.22 9.854 M 4.082 5.65 L 7.006 9.854 M 9.859 5.65 L 18.625 5.654 C 19.4 5.654 20.028 6.282 20.028 7.057 L 20.031 17.081 L 17.167 12.646 M 20.031 17.081 L 22.866 12.646"
+        d="M 14.437 18.081 L 5.475 18.095 C 4.7 18.095 4.072 17.467 4.072 16.692 L 4.082 6.65 L 1.22 10.854 M 4.082 6.65 L 7.006 10.854 M 9.859 6.65 L 18.625 6.654 C 19.4 6.654 20.028 7.282 20.028 8.057 L 20.031 18.081 L 17.167 13.646 M 20.031 18.081 L 22.866 13.646"
       />
     </Svg>
   )
diff --git a/src/lib/media/manip.ts b/src/lib/media/manip.ts
index f77b861e2..3b3ff8c6d 100644
--- a/src/lib/media/manip.ts
+++ b/src/lib/media/manip.ts
@@ -1,10 +1,10 @@
 import RNFetchBlob from 'rn-fetch-blob'
 import ImageResizer from '@bam.tech/react-native-image-resizer'
-import {Image as RNImage, Share} from 'react-native'
+import {Image as RNImage} from 'react-native'
 import {Image} from 'react-native-image-crop-picker'
 import RNFS from 'react-native-fs'
 import uuid from 'react-native-uuid'
-import * as Toast from 'view/com/util/Toast'
+import * as Sharing from 'expo-sharing'
 import {Dimensions} from './types'
 import {POST_IMG_MAX} from 'lib/constants'
 import {isAndroid} from 'platform/detection'
@@ -120,20 +120,19 @@ export async function downloadAndResize(opts: DownloadAndResizeOpts) {
 }
 
 export async function saveImageModal({uri}: {uri: string}) {
+  if (!(await Sharing.isAvailableAsync())) {
+    // TODO might need to give an error to the user in this case -prf
+    return
+  }
   const downloadResponse = await RNFetchBlob.config({
     fileCache: true,
   }).fetch('GET', uri)
 
-  const imagePath = downloadResponse.path()
-  const base64Data = await downloadResponse.readFile('base64')
-  const result = await Share.share({
-    url: 'data:image/png;base64,' + base64Data,
+  let imagePath = downloadResponse.path()
+  await Sharing.shareAsync(normalizePath(imagePath, true), {
+    mimeType: 'image/png',
+    UTI: 'public.png',
   })
-  if (result.action === Share.sharedAction) {
-    Toast.show('Image saved to gallery')
-  } else if (result.action === Share.dismissedAction) {
-    // dismissed
-  }
   RNFS.unlink(imagePath)
 }
 
@@ -201,8 +200,8 @@ async function moveToPermanentPath(path: string): Promise<string> {
   return normalizePath(destinationPath)
 }
 
-function normalizePath(str: string): string {
-  if (isAndroid) {
+function normalizePath(str: string, allPlatforms = false): string {
+  if (isAndroid || allPlatforms) {
     if (!str.startsWith('file://')) {
       return `file://${str}`
     }
diff --git a/src/lib/routes/back-handler.ts b/src/lib/routes/back-handler.ts
index feb928458..c4067c53e 100644
--- a/src/lib/routes/back-handler.ts
+++ b/src/lib/routes/back-handler.ts
@@ -1,11 +1,8 @@
 import {BackHandler} from 'react-native'
 import {RootStoreModel} from 'state/index'
 
-export function onBack(cb: () => boolean): () => void {
-  const subscription = BackHandler.addEventListener('hardwareBackPress', cb)
-  return () => subscription.remove()
-}
-
 export function init(store: RootStoreModel) {
-  onBack(() => store.shell.closeAnyActiveElement())
+  BackHandler.addEventListener('hardwareBackPress', () => {
+    return store.shell.closeAnyActiveElement()
+  })
 }
diff --git a/src/lib/themes.ts b/src/lib/themes.ts
index 76d4fbf2f..95aee0842 100644
--- a/src/lib/themes.ts
+++ b/src/lib/themes.ts
@@ -291,8 +291,8 @@ export const darkTheme: Theme = {
   palette: {
     ...defaultTheme.palette,
     default: {
-      background: colors.gray8,
-      backgroundLight: colors.gray6,
+      background: colors.black,
+      backgroundLight: colors.gray7,
       text: colors.white,
       textLight: colors.gray3,
       textInverted: colors.black,
@@ -307,7 +307,7 @@ export const darkTheme: Theme = {
       replyLineDot: colors.gray6,
       unreadNotifBg: colors.blue7,
       unreadNotifBorder: colors.blue6,
-      postCtrl: '#61657A',
+      postCtrl: '#707489',
       brandText: '#0085ff',
       emptyStateIcon: colors.gray4,
     },
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 275001309..78c5fd6ea 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -33,7 +33,7 @@ import {OpenCameraBtn} from './photos/OpenCameraBtn'
 import {usePalette} from 'lib/hooks/usePalette'
 import QuoteEmbed from '../util/post-embeds/QuoteEmbed'
 import {useExternalLinkFetch} from './useExternalLinkFetch'
-import {isDesktopWeb} from 'platform/detection'
+import {isDesktopWeb, isAndroid} from 'platform/detection'
 import {GalleryModel} from 'state/models/media/gallery'
 import {Gallery} from './photos/Gallery'
 
@@ -195,8 +195,8 @@ export const ComposePost = observer(function ComposePost({
 
   const canSelectImages = gallery.size <= 4
   const viewStyles = {
-    paddingBottom: Platform.OS === 'android' ? insets.bottom : 0,
-    paddingTop: Platform.OS === 'android' ? insets.top : 15,
+    paddingBottom: isAndroid ? insets.bottom : 0,
+    paddingTop: isAndroid ? insets.top : isDesktopWeb ? 0 : 15,
   }
 
   return (
diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx
index e1972f89c..07d5168ed 100644
--- a/src/view/com/modals/Modal.web.tsx
+++ b/src/view/com/modals/Modal.web.tsx
@@ -97,6 +97,7 @@ function Modal({modal}: {modal: ModalIface}) {
               styles.container,
               isMobileWeb && styles.containerMobile,
               pal.view,
+              pal.border,
             ]}>
             {element}
           </View>
@@ -124,6 +125,7 @@ const styles = StyleSheet.create({
     paddingVertical: 20,
     paddingHorizontal: 24,
     borderRadius: 8,
+    borderWidth: 1,
   },
   containerMobile: {
     borderRadius: 0,
diff --git a/src/view/com/util/forms/DropdownButton.tsx b/src/view/com/util/forms/DropdownButton.tsx
index 2aeae9bae..fcb209005 100644
--- a/src/view/com/util/forms/DropdownButton.tsx
+++ b/src/view/com/util/forms/DropdownButton.tsx
@@ -291,6 +291,8 @@ const DropdownItems = ({
   const theme = useTheme()
   const dropDownBackgroundColor =
     theme.colorScheme === 'dark' ? pal.btn : pal.view
+  const separatorColor =
+    theme.colorScheme === 'dark' ? pal.borderDark : pal.border
 
   return (
     <>
@@ -322,7 +324,9 @@ const DropdownItems = ({
               </TouchableOpacity>
             )
           } else if (isSep(item)) {
-            return <View key={index} style={[styles.separator, pal.border]} />
+            return (
+              <View key={index} style={[styles.separator, separatorColor]} />
+            )
           }
           return null
         })}
diff --git a/src/view/screens/Settings.tsx b/src/view/screens/Settings.tsx
index 6cf83c391..89e2d78b4 100644
--- a/src/view/screens/Settings.tsx
+++ b/src/view/screens/Settings.tsx
@@ -35,6 +35,7 @@ import {AccountData} from 'state/models/session'
 import {useAnalytics} from 'lib/analytics'
 import {NavigationProp} from 'lib/routes/types'
 import {pluralize} from 'lib/strings/helpers'
+import {isDesktopWeb} from 'platform/detection'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
 export const SettingsScreen = withAuthRequired(
@@ -139,9 +140,12 @@ export const SettingsScreen = withAuthRequired(
     }, [store])
 
     return (
-      <View style={[s.hContentRegion]} testID="settingsScreen">
-        <ViewHeader title="Settings" showOnDesktop />
-        <ScrollView style={s.hContentRegion} scrollIndicatorInsets={{right: 1}}>
+      <View style={s.hContentRegion} testID="settingsScreen">
+        <ViewHeader title="Settings" />
+        <ScrollView
+          style={s.hContentRegion}
+          contentContainerStyle={!isDesktopWeb && pal.viewLight}
+          scrollIndicatorInsets={{right: 1}}>
           <View style={styles.spacer20} />
           <View style={[s.flexRow, styles.heading]}>
             <Text type="xl-bold" style={pal.text}>
diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx
index ed0450c01..0e5b82423 100644
--- a/src/view/shell/Composer.web.tsx
+++ b/src/view/shell/Composer.web.tsx
@@ -32,7 +32,7 @@ export const Composer = observer(
 
     return (
       <View style={styles.mask}>
-        <View style={[styles.container, pal.view]}>
+        <View style={[styles.container, pal.view, pal.border]}>
           <ComposePost
             replyTo={replyTo}
             quote={quote}
@@ -63,5 +63,6 @@ const styles = StyleSheet.create({
     paddingHorizontal: 2,
     borderRadius: isMobileWeb ? 0 : 8,
     marginBottom: '10vh',
+    borderWidth: 1,
   },
 })
diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx
index e0abec777..04ea7c9bf 100644
--- a/src/view/shell/index.tsx
+++ b/src/view/shell/index.tsx
@@ -13,6 +13,7 @@ import {DrawerContent} from './Drawer'
 import {Composer} from './Composer'
 import {useTheme} from 'lib/ThemeContext'
 import {usePalette} from 'lib/hooks/usePalette'
+import * as backHandler from 'lib/routes/back-handler'
 import {RoutesContainer, TabsNavigator} from '../../Navigation'
 import {isStateAtTabRoot} from 'lib/routes/helpers'
 
@@ -34,6 +35,9 @@ const ShellInner = observer(() => {
     [store],
   )
   const canGoBack = useNavigationState(state => !isStateAtTabRoot(state))
+  React.useEffect(() => {
+    backHandler.init(store)
+  }, [store])
 
   return (
     <>
@@ -69,8 +73,8 @@ const ShellInner = observer(() => {
 })
 
 export const Shell: React.FC = observer(() => {
-  const theme = useTheme()
   const pal = usePalette('default')
+  const theme = useTheme()
   return (
     <View testID="mobileShellView" style={[styles.outerContainer, pal.view]}>
       <StatusBar style={theme.colorScheme === 'dark' ? 'light' : 'dark'} />