#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>
zio/stable
Ansh 2023-04-12 18:49:40 -07:00 committed by GitHub
parent 05e4e4ff93
commit f50f07f562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 21 deletions

View File

@ -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

View File

@ -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} />

View File

@ -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
}

View File

@ -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" />

View File

@ -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,

View File

@ -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,
},
})

View File

@ -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)',