about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAnsh <anshnanda10@gmail.com>2023-04-12 18:49:40 -0700
committerGitHub <noreply@github.com>2023-04-12 18:49:40 -0700
commitf50f07f562b82e15be28aa750d7e45629081faa3 (patch)
treefe814bd142983f3e734949b7f95efeb8130edd0a
parent05e4e4ff93b0e4b7c5515852017be046ebc3859c (diff)
downloadvoidsky-f50f07f562b82e15be28aa750d7e45629081faa3.tar.zst
#435 web dark mode (#455)
* add ThemeProvider to App.web.tsx

* make FlatNavigator use themed color

* fix extra padding on top in web

* add observer to App.web.tsx to make it react to theme changes

* fix TS for useColorSchemeStyle

* add dark mode toggle button to web LeftNav

* fix index.web.tsx border colors for web

* Move the darkmode desktop web toggle to the right nav column

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
-rw-r--r--src/App.web.tsx28
-rw-r--r--src/Navigation.tsx4
-rw-r--r--src/lib/hooks/useColorSchemeStyle.ts2
-rw-r--r--src/view/screens/Home.tsx5
-rw-r--r--src/view/shell/desktop/LeftNav.tsx3
-rw-r--r--src/view/shell/desktop/RightNav.tsx35
-rw-r--r--src/view/shell/index.web.tsx19
7 files changed, 75 insertions, 21 deletions
diff --git a/src/App.web.tsx b/src/App.web.tsx
index 3f79f06b2..e259a48e9 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -6,8 +6,10 @@ import * as analytics from 'lib/analytics'
 import {RootStoreModel, setupState, RootStoreProvider} from './state'
 import {Shell} from './view/shell/index'
 import {ToastContainer} from './view/com/util/Toast.web'
+import {ThemeProvider} from 'lib/ThemeContext'
+import {observer} from 'mobx-react-lite'
 
-function App() {
+const App = observer(() => {
   const [rootStore, setRootStore] = useState<RootStoreModel | undefined>(
     undefined,
   )
@@ -27,17 +29,19 @@ function App() {
   }
 
   return (
-    <RootSiblingParent>
-      <analytics.Provider>
-        <RootStoreProvider value={rootStore}>
-          <SafeAreaProvider>
-            <Shell />
-          </SafeAreaProvider>
-          <ToastContainer />
-        </RootStoreProvider>
-      </analytics.Provider>
-    </RootSiblingParent>
+    <ThemeProvider theme={rootStore.shell.darkMode ? 'dark' : 'light'}>
+      <RootSiblingParent>
+        <analytics.Provider>
+          <RootStoreProvider value={rootStore}>
+            <SafeAreaProvider>
+              <Shell />
+            </SafeAreaProvider>
+            <ToastContainer />
+          </RootStoreProvider>
+        </analytics.Provider>
+      </RootSiblingParent>
+    </ThemeProvider>
   )
-}
+})
 
 export default App
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
index 648859f16..0de31a4ad 100644
--- a/src/Navigation.tsx
+++ b/src/Navigation.tsx
@@ -40,6 +40,7 @@ import {PrivacyPolicyScreen} from './view/screens/PrivacyPolicy'
 import {TermsOfServiceScreen} from './view/screens/TermsOfService'
 import {CommunityGuidelinesScreen} from './view/screens/CommunityGuidelines'
 import {CopyrightPolicyScreen} from './view/screens/CopyrightPolicy'
+import {usePalette} from 'lib/hooks/usePalette'
 
 const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
 
@@ -162,6 +163,7 @@ function NotificationsTabNavigator() {
  * in a single ("flat") stack.
  */
 function FlatNavigator() {
+  const pal = usePalette('default')
   return (
     <Flat.Navigator
       screenOptions={{
@@ -169,7 +171,7 @@ function FlatNavigator() {
         fullScreenGestureEnabled: true,
         headerShown: false,
         animationDuration: 250,
-        contentStyle: {backgroundColor: 'white'},
+        contentStyle: [pal.view],
       }}>
       <Flat.Screen name="Home" component={HomeScreen} />
       <Flat.Screen name="Search" component={SearchScreen} />
diff --git a/src/lib/hooks/useColorSchemeStyle.ts b/src/lib/hooks/useColorSchemeStyle.ts
index 18c48b961..100dc44e4 100644
--- a/src/lib/hooks/useColorSchemeStyle.ts
+++ b/src/lib/hooks/useColorSchemeStyle.ts
@@ -1,6 +1,6 @@
 import {useTheme} from 'lib/ThemeContext'
 
-export function useColorSchemeStyle(lightStyle: any, darkStyle: any) {
+export function useColorSchemeStyle<T>(lightStyle: T, darkStyle: T) {
   const colorScheme = useTheme().colorScheme
   return colorScheme === 'dark' ? darkStyle : lightStyle
 }
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 23d1e2b9d..ca9c25f55 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import {FlatList, View} from 'react-native'
+import {FlatList, View, Platform} from 'react-native'
 import {useFocusEffect, useIsFocused} from '@react-navigation/native'
 import {observer} from 'mobx-react-lite'
 import useAppState from 'react-native-appstate-hook'
@@ -187,12 +187,11 @@ const FeedPage = observer(
           key="default"
           feed={feed}
           scrollElRef={scrollElRef}
-          style={s.hContentRegion}
           showPostFollowBtn
           onPressTryAgain={onPressTryAgain}
           onScroll={onMainScroll}
           renderEmptyState={renderEmptyState}
-          headerOffset={HEADER_OFFSET}
+          headerOffset={Platform.OS === 'web' ? 0 : HEADER_OFFSET} // only offset on mobile
         />
         {feed.hasNewLatest && !feed.isRefreshing && (
           <LoadLatestBtn onPress={onPressLoadLatest} label="posts" />
diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx
index 45dd6579f..e9a631b23 100644
--- a/src/view/shell/desktop/LeftNav.tsx
+++ b/src/view/shell/desktop/LeftNav.tsx
@@ -130,7 +130,7 @@ export const DesktopLeftNav = observer(function DesktopLeftNav() {
   const pal = usePalette('default')
 
   return (
-    <View style={styles.leftNav}>
+    <View style={[styles.leftNav, pal.view]}>
       {store.session.hasSession && <ProfileCard />}
       <BackBtn />
       <NavItem
@@ -246,6 +246,7 @@ const styles = StyleSheet.create({
     paddingHorizontal: 16,
     backgroundColor: colors.blue3,
     marginTop: 20,
+    marginBottom: 10,
   },
   newPostBtnIconWrapper: {
     marginRight: 8,
diff --git a/src/view/shell/desktop/RightNav.tsx b/src/view/shell/desktop/RightNav.tsx
index 84a7593ca..7a3388f88 100644
--- a/src/view/shell/desktop/RightNav.tsx
+++ b/src/view/shell/desktop/RightNav.tsx
@@ -10,10 +10,18 @@ import {FEEDBACK_FORM_URL} from 'lib/constants'
 import {s} from 'lib/styles'
 import {useStores} from 'state/index'
 import {pluralize} from 'lib/strings/helpers'
+import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
+import {MoonIcon} from 'lib/icons'
 
 export const DesktopRightNav = observer(function DesktopRightNav() {
   const store = useStores()
   const pal = usePalette('default')
+  const mode = useColorSchemeStyle('Light', 'Dark')
+
+  const onDarkmodePress = React.useCallback(() => {
+    store.shell.setDarkMode(!store.shell.darkMode)
+  }, [store])
+
   return (
     <View style={[styles.rightNav, pal.view]}>
       {store.session.hasSession && <DesktopSearch />}
@@ -50,6 +58,18 @@ export const DesktopRightNav = observer(function DesktopRightNav() {
         </View>
       </View>
       <InviteCodes />
+      <View>
+        <TouchableOpacity
+          style={[styles.darkModeToggle]}
+          onPress={onDarkmodePress}>
+          <View style={[pal.viewLight, styles.darkModeToggleIcon]}>
+            <MoonIcon size={18} style={pal.textLight} />
+          </View>
+          <Text type="sm" style={pal.textLight}>
+            {mode} mode
+          </Text>
+        </TouchableOpacity>
+      </View>
     </View>
   )
 })
@@ -110,4 +130,19 @@ const styles = StyleSheet.create({
   inviteCodesIcon: {
     marginRight: 6,
   },
+
+  darkModeToggle: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    gap: 8,
+    marginHorizontal: 12,
+  },
+  darkModeToggleIcon: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    justifyContent: 'center',
+    width: 26,
+    height: 26,
+    borderRadius: 15,
+  },
 })
diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx
index 86d120127..5d7ed259a 100644
--- a/src/view/shell/index.web.tsx
+++ b/src/view/shell/index.web.tsx
@@ -14,9 +14,11 @@ import {RoutesContainer, FlatNavigator} from '../../Navigation'
 import {DrawerContent} from './Drawer'
 import {useWebMediaQueries} from '../../lib/hooks/useWebMediaQueries'
 import {BottomBarWeb} from './bottom-bar/BottomBarWeb'
+import {usePalette} from 'lib/hooks/usePalette'
 
 const ShellInner = observer(() => {
   const store = useStores()
+  const pal = usePalette('default')
   const {isDesktop} = useWebMediaQueries()
 
   return (
@@ -30,8 +32,20 @@ const ShellInner = observer(() => {
         <>
           <DesktopLeftNav />
           <DesktopRightNav />
-          <View style={[styles.viewBorder, styles.viewBorderLeft]} />
-          <View style={[styles.viewBorder, styles.viewBorderRight]} />
+          <View
+            style={[
+              styles.viewBorder,
+              {borderLeftColor: pal.colors.border},
+              styles.viewBorderLeft,
+            ]}
+          />
+          <View
+            style={[
+              styles.viewBorder,
+              {borderLeftColor: pal.colors.border},
+              styles.viewBorderRight,
+            ]}
+          />
         </>
       )}
       <Composer
@@ -81,7 +95,6 @@ const styles = StyleSheet.create({
     width: 1,
     height: '100%',
     borderLeftWidth: 1,
-    borderLeftColor: colors.gray2,
   },
   viewBorderLeft: {
     left: 'calc(50vw - 300px)',