mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 22:49:45 +01:00
add support to change theme based on system
This commit is contained in:
@@ -11,11 +11,16 @@ import {db, DDS, ToastEvent} from './src/utils/utils';
|
|||||||
import {useNetInfo} from '@react-native-community/netinfo';
|
import {useNetInfo} from '@react-native-community/netinfo';
|
||||||
import RNHTMLtoPDF from 'react-native-html-to-pdf';
|
import RNHTMLtoPDF from 'react-native-html-to-pdf';
|
||||||
import { MMKV } from './src/utils/storage';
|
import { MMKV } from './src/utils/storage';
|
||||||
|
import {
|
||||||
|
Appearance,
|
||||||
|
useColorScheme,
|
||||||
|
StatusBar} from "react-native";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [state, dispatch] = useTracked();
|
const [state, dispatch] = useTracked();
|
||||||
const [init, setInit] = useState(false);
|
const [init, setInit] = useState(false);
|
||||||
const netInfo = useNetInfo();
|
const netInfo = useNetInfo();
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
const I = DDS.isTab ? require('./index.tablet') : require('./index.mobile');
|
const I = DDS.isTab ? require('./index.tablet') : require('./index.mobile');
|
||||||
const _onOrientationChange = o => {
|
const _onOrientationChange = o => {
|
||||||
// Currently orientation is locked on tablet.
|
// Currently orientation is locked on tablet.
|
||||||
@@ -26,6 +31,31 @@ const App = () => {
|
|||||||
}, 1000); */
|
}, 1000); */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
systemThemeChange();
|
||||||
|
|
||||||
|
},[colorScheme])
|
||||||
|
|
||||||
|
|
||||||
|
const systemThemeChange = async () => {
|
||||||
|
let s;
|
||||||
|
try {
|
||||||
|
s = await MMKV.getStringAsync('settings');
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
console.log("HEREE");
|
||||||
|
console.log('heree');
|
||||||
|
if (!s) return;
|
||||||
|
s = JSON.parse(s);
|
||||||
|
console.log(s);
|
||||||
|
if (s.useSystemTheme) {
|
||||||
|
let newColors = await getColorScheme(s.useSystemTheme);
|
||||||
|
StatusBar.setBarStyle(Appearance.getColorScheme() === "dark" ? 'light-content' : 'dark-content');
|
||||||
|
dispatch({type: ACTIONS.THEME, colors: newColors});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!netInfo.isConnected || !netInfo.isInternetReachable) {
|
if (!netInfo.isConnected || !netInfo.isInternetReachable) {
|
||||||
db.user?.get().then(user => {
|
db.user?.get().then(user => {
|
||||||
@@ -111,7 +141,6 @@ const App = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
async function Initialize(colors = colors) {
|
async function Initialize(colors = colors) {
|
||||||
let newColors = await getColorScheme(colors);
|
|
||||||
|
|
||||||
let s;
|
let s;
|
||||||
try {
|
try {
|
||||||
@@ -136,6 +165,7 @@ const App = () => {
|
|||||||
dispatch({type: ACTIONS.SETTINGS, settings: {...s}});
|
dispatch({type: ACTIONS.SETTINGS, settings: {...s}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let newColors = await getColorScheme(s.useSystemTheme);
|
||||||
dispatch({type: ACTIONS.THEME, colors: newColors});
|
dispatch({type: ACTIONS.THEME, colors: newColors});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Dimensions, PixelRatio, StatusBar, Platform } from 'react-native';
|
import { Dimensions, PixelRatio, StatusBar, Platform, Appearance } from 'react-native';
|
||||||
import {
|
import {
|
||||||
eSendEvent,
|
eSendEvent,
|
||||||
eSubscribeEvent,
|
eSubscribeEvent,
|
||||||
@@ -185,7 +185,7 @@ export function setColorScheme(colors = COLOR_SCHEME, accent = ACCENT) {
|
|||||||
return COLOR_SCHEME;
|
return COLOR_SCHEME;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getColorScheme() {
|
export async function getColorScheme(useSystemTheme) {
|
||||||
let accentColor;
|
let accentColor;
|
||||||
try {
|
try {
|
||||||
accentColor = await MMKV.getStringAsync('accentColor');
|
accentColor = await MMKV.getStringAsync('accentColor');
|
||||||
@@ -201,13 +201,16 @@ export async function getColorScheme() {
|
|||||||
} else {
|
} else {
|
||||||
setAccentColor(accentColor);
|
setAccentColor(accentColor);
|
||||||
}
|
}
|
||||||
|
if (useSystemTheme) {
|
||||||
|
|
||||||
|
StatusBar.setBarStyle(Appearance.getColorScheme() === "dark" ? 'light-content' : 'dark-content');
|
||||||
|
return Appearance.getColorScheme() === "dark" ? COLOR_SCHEME_DARK : COLOR_SCHEME_LIGHT
|
||||||
|
}
|
||||||
if (typeof t !== 'string') {
|
if (typeof t !== 'string') {
|
||||||
MMKV.setStringAsync('theme', JSON.stringify({ night: false }));
|
MMKV.setStringAsync('theme', JSON.stringify({ night: false }));
|
||||||
setColorScheme(COLOR_SCHEME_LIGHT);
|
setColorScheme(COLOR_SCHEME_LIGHT);
|
||||||
} else {
|
} else {
|
||||||
let themeToSet = JSON.parse(t);
|
let themeToSet = JSON.parse(t);
|
||||||
|
|
||||||
themeToSet.night
|
themeToSet.night
|
||||||
? setColorScheme(COLOR_SCHEME_DARK)
|
? setColorScheme(COLOR_SCHEME_DARK)
|
||||||
: setColorScheme(COLOR_SCHEME_LIGHT);
|
: setColorScheme(COLOR_SCHEME_LIGHT);
|
||||||
|
|||||||
@@ -258,22 +258,19 @@ export class AddNotebookDialog extends React.Component {
|
|||||||
style={styles.wrapper}>
|
style={styles.wrapper}>
|
||||||
<TouchableOpacity onPress={this.close} style={styles.overlay} />
|
<TouchableOpacity onPress={this.close} style={styles.overlay} />
|
||||||
<View
|
<View
|
||||||
style={{
|
style={[
|
||||||
width: DDS.isTab ? '50%' : '100%',
|
styles.container,
|
||||||
height: DDS.isTab ? '80%' : '100%',
|
{
|
||||||
maxHeight: DDS.isTab ? '80%' : '100%',
|
backgroundColor: colors.bg,
|
||||||
borderRadius: DDS.isTab ? 5 : 0,
|
},
|
||||||
backgroundColor: colors.bg,
|
]}>
|
||||||
paddingHorizontal: ph,
|
|
||||||
paddingVertical: pv,
|
|
||||||
}}>
|
|
||||||
<View style={styles.headingContainer}>
|
<View style={styles.headingContainer}>
|
||||||
<Icon
|
<Icon
|
||||||
name="book-outline"
|
name="book-outline"
|
||||||
color={colors.accent}
|
color={colors.accent}
|
||||||
size={SIZE.xl}
|
size={SIZE.xl}
|
||||||
/>
|
/>
|
||||||
<Text style={[styles.headingText,{color:colors.accent}]}>
|
<Text style={[styles.headingText, {color: colors.accent}]}>
|
||||||
{toEdit && toEdit.dateCreated
|
{toEdit && toEdit.dateCreated
|
||||||
? 'Edit Notebook'
|
? 'Edit Notebook'
|
||||||
: 'New Notebook'}
|
: 'New Notebook'}
|
||||||
@@ -516,6 +513,14 @@ const styles = StyleSheet.create({
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
|
container: {
|
||||||
|
width: DDS.isTab ? '50%' : '100%',
|
||||||
|
height: DDS.isTab ? '80%' : '100%',
|
||||||
|
maxHeight: DDS.isTab ? '80%' : '100%',
|
||||||
|
borderRadius: DDS.isTab ? 5 : 0,
|
||||||
|
paddingHorizontal: ph,
|
||||||
|
paddingVertical: pv,
|
||||||
|
},
|
||||||
overlay: {
|
overlay: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export const defaultState = {
|
|||||||
showKeyboardOnOpen: false,
|
showKeyboardOnOpen: false,
|
||||||
fontScale: 1,
|
fontScale: 1,
|
||||||
forcePortraitOnTablet: false,
|
forcePortraitOnTablet: false,
|
||||||
|
useSystemTheme:true
|
||||||
},
|
},
|
||||||
currentScreen: 'home',
|
currentScreen: 'home',
|
||||||
colors: {
|
colors: {
|
||||||
|
|||||||
@@ -1,19 +1,41 @@
|
|||||||
import { useIsFocused } from '@react-navigation/native';
|
import {useIsFocused} from '@react-navigation/native';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Clipboard, Linking, Modal, Platform, ScrollView, StatusBar, Text, TouchableOpacity, View } from 'react-native';
|
import {
|
||||||
|
Clipboard,
|
||||||
|
Linking,
|
||||||
|
Modal,
|
||||||
|
Platform,
|
||||||
|
ScrollView,
|
||||||
|
StatusBar,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
View,
|
||||||
|
Appearance,
|
||||||
|
} from 'react-native';
|
||||||
import * as Animatable from 'react-native-animatable';
|
import * as Animatable from 'react-native-animatable';
|
||||||
|
|
||||||
import QRCode from 'react-native-qrcode-generator';
|
import QRCode from 'react-native-qrcode-generator';
|
||||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
import { ACCENT, COLOR_SCHEME, COLOR_SCHEME_DARK, COLOR_SCHEME_LIGHT, opacity, ph, pv, setColorScheme, SIZE, WEIGHT } from '../../common/common';
|
import {
|
||||||
import { Toast } from '../../components/Toast';
|
ACCENT,
|
||||||
import { useTracked } from '../../provider';
|
COLOR_SCHEME,
|
||||||
import { ACTIONS } from '../../provider/actions';
|
COLOR_SCHEME_DARK,
|
||||||
import { eSendEvent } from '../../services/eventManager';
|
COLOR_SCHEME_LIGHT,
|
||||||
import { eOpenLoginDialog, eResetApp } from '../../services/events';
|
opacity,
|
||||||
|
ph,
|
||||||
|
pv,
|
||||||
|
setColorScheme,
|
||||||
|
SIZE,
|
||||||
|
WEIGHT,
|
||||||
|
} from '../../common/common';
|
||||||
|
import {Toast} from '../../components/Toast';
|
||||||
|
import {useTracked} from '../../provider';
|
||||||
|
import {ACTIONS} from '../../provider/actions';
|
||||||
|
import {eSendEvent} from '../../services/eventManager';
|
||||||
|
import {eOpenLoginDialog, eResetApp} from '../../services/events';
|
||||||
import NavigationService from '../../services/NavigationService';
|
import NavigationService from '../../services/NavigationService';
|
||||||
import { db, DDS, setSetting, ToastEvent, w } from '../../utils/utils';
|
import {db, DDS, setSetting, ToastEvent, w} from '../../utils/utils';
|
||||||
import { MMKV } from '../../utils/storage';
|
import {MMKV} from '../../utils/storage';
|
||||||
|
|
||||||
export const Settings = ({route, navigation}) => {
|
export const Settings = ({route, navigation}) => {
|
||||||
const [state, dispatch] = useTracked();
|
const [state, dispatch] = useTracked();
|
||||||
@@ -332,7 +354,7 @@ export const Settings = ({route, navigation}) => {
|
|||||||
ToastEvent.show('Logged out, syncing disabled', 'success');
|
ToastEvent.show('Logged out, syncing disabled', 'success');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
].map(item => (
|
].map((item) => (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
key={item.name}
|
key={item.name}
|
||||||
activeOpacity={opacity}
|
activeOpacity={opacity}
|
||||||
@@ -479,7 +501,7 @@ export const Settings = ({route, navigation}) => {
|
|||||||
'#f032e6',
|
'#f032e6',
|
||||||
'#bcf60c',
|
'#bcf60c',
|
||||||
'#fabebe',
|
'#fabebe',
|
||||||
].map(item => (
|
].map((item) => (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
key={item}
|
key={item}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
@@ -510,6 +532,54 @@ export const Settings = ({route, navigation}) => {
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={async () => {
|
||||||
|
await setSetting(
|
||||||
|
settings,
|
||||||
|
'useSystemTheme',
|
||||||
|
!settings.useSystemTheme,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!settings.useSystemTheme) {
|
||||||
|
MMKV.setStringAsync(
|
||||||
|
'theme',
|
||||||
|
JSON.stringify({night: Appearance.getColorScheme() === 'dark'}),
|
||||||
|
);
|
||||||
|
changeColorScheme(
|
||||||
|
Appearance.getColorScheme() === 'dark'
|
||||||
|
? COLOR_SCHEME_DARK
|
||||||
|
: COLOR_SCHEME_LIGHT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
activeOpacity={opacity}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
marginHorizontal: 0,
|
||||||
|
paddingVertical: pv + 5,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: SIZE.sm,
|
||||||
|
fontFamily: WEIGHT.regular,
|
||||||
|
textAlignVertical: 'center',
|
||||||
|
color: colors.pri,
|
||||||
|
}}>
|
||||||
|
Use System Dark Mode
|
||||||
|
</Text>
|
||||||
|
<Icon
|
||||||
|
size={SIZE.xl}
|
||||||
|
color={settings.useSystemTheme ? colors.accent : colors.icon}
|
||||||
|
name={
|
||||||
|
settings.useSystemTheme ? 'toggle-switch' : 'toggle-switch-off'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
if (!colors.night) {
|
if (!colors.night) {
|
||||||
@@ -537,7 +607,7 @@ export const Settings = ({route, navigation}) => {
|
|||||||
textAlignVertical: 'center',
|
textAlignVertical: 'center',
|
||||||
color: colors.pri,
|
color: colors.pri,
|
||||||
}}>
|
}}>
|
||||||
Dark mode
|
Dark Mode
|
||||||
</Text>
|
</Text>
|
||||||
<Icon
|
<Icon
|
||||||
size={SIZE.xl}
|
size={SIZE.xl}
|
||||||
@@ -677,7 +747,7 @@ export const Settings = ({route, navigation}) => {
|
|||||||
Linking.openURL('https://www.notesnook.com');
|
Linking.openURL('https://www.notesnook.com');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
].map(item => (
|
].map((item) => (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
key={item.name}
|
key={item.name}
|
||||||
activeOpacity={opacity}
|
activeOpacity={opacity}
|
||||||
|
|||||||
Reference in New Issue
Block a user