forked from vergnet/application-amicale
Follow system night mode when available
This commit is contained in:
parent
992e2d8286
commit
9ec986574f
8 changed files with 57 additions and 17 deletions
8
App.js
8
App.js
|
@ -42,6 +42,7 @@ export default class App extends React.Component<Props, State> {
|
||||||
super();
|
super();
|
||||||
LocaleManager.initTranslations();
|
LocaleManager.initTranslations();
|
||||||
this.onIntroDone = this.onIntroDone.bind(this);
|
this.onIntroDone = this.onIntroDone.bind(this);
|
||||||
|
SplashScreen.preventAutoHide();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,13 +85,9 @@ export default class App extends React.Component<Props, State> {
|
||||||
|
|
||||||
async loadAssetsAsync() {
|
async loadAssetsAsync() {
|
||||||
// Wait for custom fonts to be loaded before showing the app
|
// Wait for custom fonts to be loaded before showing the app
|
||||||
// console.log("loading Fonts");
|
|
||||||
SplashScreen.preventAutoHide();
|
|
||||||
// console.log("loading preferences");
|
|
||||||
await AsyncStorageManager.getInstance().loadPreferences();
|
await AsyncStorageManager.getInstance().loadPreferences();
|
||||||
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
||||||
// console.log("loading Expo token");
|
// await NotificationsManager.initExpoToken();
|
||||||
await NotificationsManager.initExpoToken();
|
|
||||||
this.onLoadFinished();
|
this.onLoadFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +119,6 @@ export default class App extends React.Component<Props, State> {
|
||||||
isAprilFools={this.state.showAprilFools && !this.state.showIntro}
|
isAprilFools={this.state.showAprilFools && !this.state.showIntro}
|
||||||
/>;
|
/>;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PaperProvider theme={this.state.currentTheme}>
|
<PaperProvider theme={this.state.currentTheme}>
|
||||||
<NavigationContainer theme={this.state.currentTheme}>
|
<NavigationContainer theme={this.state.currentTheme}>
|
||||||
|
|
1
app.json
1
app.json
|
@ -13,6 +13,7 @@
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"orientation": "portrait",
|
"orientation": "portrait",
|
||||||
"primaryColor": "#be1522",
|
"primaryColor": "#be1522",
|
||||||
|
"userInterfaceStyle": "automatic",
|
||||||
"icon": "./assets/android.icon.png",
|
"icon": "./assets/android.icon.png",
|
||||||
"splash": {
|
"splash": {
|
||||||
"backgroundColor": "#be1522",
|
"backgroundColor": "#be1522",
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
"react-native-render-html": "^4.1.2",
|
"react-native-render-html": "^4.1.2",
|
||||||
"react-native-safe-area-context": "0.6.0",
|
"react-native-safe-area-context": "0.6.0",
|
||||||
"react-native-screens": "2.0.0-alpha.12",
|
"react-native-screens": "2.0.0-alpha.12",
|
||||||
"react-native-webview": "7.4.3"
|
"react-native-webview": "7.4.3",
|
||||||
|
"react-native-appearance": "~0.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-preset-expo": "^8.0.0"
|
"babel-preset-expo": "^8.0.0"
|
||||||
|
|
|
@ -7,6 +7,7 @@ import i18n from "i18n-js";
|
||||||
import AsyncStorageManager from "../utils/AsyncStorageManager";
|
import AsyncStorageManager from "../utils/AsyncStorageManager";
|
||||||
import NotificationsManager from "../utils/NotificationsManager";
|
import NotificationsManager from "../utils/NotificationsManager";
|
||||||
import {Card, List, Switch, ToggleButton} from 'react-native-paper';
|
import {Card, List, Switch, ToggleButton} from 'react-native-paper';
|
||||||
|
import {Appearance} from "react-native-appearance";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
|
@ -14,6 +15,7 @@ type Props = {
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
nightMode: boolean,
|
nightMode: boolean,
|
||||||
|
nightModeFollowSystem: boolean,
|
||||||
proxiwashNotifPickerSelected: string,
|
proxiwashNotifPickerSelected: string,
|
||||||
startScreenPickerSelected: string,
|
startScreenPickerSelected: string,
|
||||||
};
|
};
|
||||||
|
@ -24,6 +26,8 @@ type State = {
|
||||||
export default class SettingsScreen extends React.Component<Props, State> {
|
export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
state = {
|
state = {
|
||||||
nightMode: ThemeManager.getNightMode(),
|
nightMode: ThemeManager.getNightMode(),
|
||||||
|
nightModeFollowSystem: AsyncStorageManager.getInstance().preferences.nightModeFollowSystem.current === '1' &&
|
||||||
|
Appearance.getColorScheme() !== 'no-preference',
|
||||||
proxiwashNotifPickerSelected: AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current,
|
proxiwashNotifPickerSelected: AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current,
|
||||||
startScreenPickerSelected: AsyncStorageManager.getInstance().preferences.defaultStartScreen.current,
|
startScreenPickerSelected: AsyncStorageManager.getInstance().preferences.defaultStartScreen.current,
|
||||||
};
|
};
|
||||||
|
@ -31,12 +35,14 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
onProxiwashNotifPickerValueChange: Function;
|
onProxiwashNotifPickerValueChange: Function;
|
||||||
onStartScreenPickerValueChange: Function;
|
onStartScreenPickerValueChange: Function;
|
||||||
onToggleNightMode: Function;
|
onToggleNightMode: Function;
|
||||||
|
onToggleNightModeFollowSystem: Function;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.onProxiwashNotifPickerValueChange = this.onProxiwashNotifPickerValueChange.bind(this);
|
this.onProxiwashNotifPickerValueChange = this.onProxiwashNotifPickerValueChange.bind(this);
|
||||||
this.onStartScreenPickerValueChange = this.onStartScreenPickerValueChange.bind(this);
|
this.onStartScreenPickerValueChange = this.onStartScreenPickerValueChange.bind(this);
|
||||||
this.onToggleNightMode = this.onToggleNightMode.bind(this);
|
this.onToggleNightMode = this.onToggleNightMode.bind(this);
|
||||||
|
this.onToggleNightModeFollowSystem = this.onToggleNightModeFollowSystem.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,6 +125,18 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
this.setState({nightMode: !this.state.nightMode});
|
this.setState({nightMode: !this.state.nightMode});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onToggleNightModeFollowSystem() {
|
||||||
|
const value = !this.state.nightModeFollowSystem;
|
||||||
|
this.setState({nightModeFollowSystem: value});
|
||||||
|
let key = AsyncStorageManager.getInstance().preferences.nightModeFollowSystem.key;
|
||||||
|
AsyncStorageManager.getInstance().savePref(key, value ? '1' : '0');
|
||||||
|
if (value) {
|
||||||
|
const nightMode = Appearance.getColorScheme() === 'dark';
|
||||||
|
ThemeManager.getInstance().setNightMode(nightMode);
|
||||||
|
this.setState({nightMode: nightMode});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list item using a checkbox control
|
* Get a list item using a checkbox control
|
||||||
*
|
*
|
||||||
|
@ -128,7 +146,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
* @param subtitle The text to display as this list item subtitle
|
* @param subtitle The text to display as this list item subtitle
|
||||||
* @returns {React.Node}
|
* @returns {React.Node}
|
||||||
*/
|
*/
|
||||||
getToggleItem(onPressCallback: Function, icon: string, title: string, subtitle: string) {
|
getToggleItem(onPressCallback: Function, icon: string, title: string, subtitle: string, state: boolean) {
|
||||||
return (
|
return (
|
||||||
<List.Item
|
<List.Item
|
||||||
title={title}
|
title={title}
|
||||||
|
@ -136,7 +154,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
left={props => <List.Icon {...props} icon={icon}/>}
|
left={props => <List.Icon {...props} icon={icon}/>}
|
||||||
right={props =>
|
right={props =>
|
||||||
<Switch
|
<Switch
|
||||||
value={this.state.nightMode}
|
value={state}
|
||||||
onValueChange={onPressCallback}
|
onValueChange={onPressCallback}
|
||||||
/>}
|
/>}
|
||||||
/>
|
/>
|
||||||
|
@ -149,14 +167,27 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
<Card style={{margin: 5}}>
|
<Card style={{margin: 5}}>
|
||||||
<Card.Title title={i18n.t('settingsScreen.generalCard')}/>
|
<Card.Title title={i18n.t('settingsScreen.generalCard')}/>
|
||||||
<List.Section>
|
<List.Section>
|
||||||
{this.getToggleItem(
|
{Appearance.getColorScheme() !== 'no-preference' ? this.getToggleItem(
|
||||||
|
this.onToggleNightModeFollowSystem,
|
||||||
|
'theme-light-dark',
|
||||||
|
i18n.t('settingsScreen.nightModeAuto'),
|
||||||
|
this.state.nightMode ?
|
||||||
|
i18n.t('settingsScreen.nightModeSubOn') :
|
||||||
|
i18n.t('settingsScreen.nightModeSubOff'),
|
||||||
|
this.state.nightModeFollowSystem
|
||||||
|
) : null}
|
||||||
|
{
|
||||||
|
Appearance.getColorScheme() === 'no-preference' || !this.state.nightModeFollowSystem ?
|
||||||
|
this.getToggleItem(
|
||||||
this.onToggleNightMode,
|
this.onToggleNightMode,
|
||||||
'theme-light-dark',
|
'theme-light-dark',
|
||||||
i18n.t('settingsScreen.nightMode'),
|
i18n.t('settingsScreen.nightMode'),
|
||||||
this.state.nightMode ?
|
this.state.nightMode ?
|
||||||
i18n.t('settingsScreen.nightModeSubOn') :
|
i18n.t('settingsScreen.nightModeSubOn') :
|
||||||
i18n.t('settingsScreen.nightModeSubOff')
|
i18n.t('settingsScreen.nightModeSubOff'),
|
||||||
)}
|
this.state.nightMode
|
||||||
|
) : null
|
||||||
|
}
|
||||||
<List.Accordion
|
<List.Accordion
|
||||||
title={i18n.t('settingsScreen.startScreen')}
|
title={i18n.t('settingsScreen.startScreen')}
|
||||||
description={i18n.t('settingsScreen.startScreenSub')}
|
description={i18n.t('settingsScreen.startScreenSub')}
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
"nightMode": "Night Mode",
|
"nightMode": "Night Mode",
|
||||||
"nightModeSubOn": "Your eyes are at peace",
|
"nightModeSubOn": "Your eyes are at peace",
|
||||||
"nightModeSubOff": "Your eyes are burning",
|
"nightModeSubOff": "Your eyes are burning",
|
||||||
|
"nightModeAuto": "Follow system dark mode",
|
||||||
"startScreen": "Start Screen",
|
"startScreen": "Start Screen",
|
||||||
"startScreenSub": "Select which screen to start the app on",
|
"startScreenSub": "Select which screen to start the app on",
|
||||||
"proxiwashNotifReminder": "Machine running reminder",
|
"proxiwashNotifReminder": "Machine running reminder",
|
||||||
|
|
|
@ -65,8 +65,9 @@
|
||||||
"settingsScreen": {
|
"settingsScreen": {
|
||||||
"generalCard": "Général",
|
"generalCard": "Général",
|
||||||
"nightMode": "Mode Nuit",
|
"nightMode": "Mode Nuit",
|
||||||
"nightModeSubOn": "Vos yeux brulent",
|
"nightModeSubOn": "Vos yeux vous remercient",
|
||||||
"nightModeSubOff": "Vos yeux vous remercient",
|
"nightModeSubOff": "Vos yeux brulent",
|
||||||
|
"nightModeAuto": "Mode nuit système",
|
||||||
"startScreen": "Écran de démarrage",
|
"startScreen": "Écran de démarrage",
|
||||||
"startScreenSub": "Choisissez l'écran utilisé au démarrage",
|
"startScreenSub": "Choisissez l'écran utilisé au démarrage",
|
||||||
"proxiwashNotifReminder": "Rappel de machine en cours",
|
"proxiwashNotifReminder": "Rappel de machine en cours",
|
||||||
|
|
|
@ -44,6 +44,11 @@ export default class AsyncStorageManager {
|
||||||
default: '[]',
|
default: '[]',
|
||||||
current: '',
|
current: '',
|
||||||
},
|
},
|
||||||
|
nightModeFollowSystem: {
|
||||||
|
key: 'nightModeFollowSystem',
|
||||||
|
default: '1',
|
||||||
|
current: '',
|
||||||
|
},
|
||||||
nightMode: {
|
nightMode: {
|
||||||
key: 'nightMode',
|
key: 'nightMode',
|
||||||
default: '0',
|
default: '0',
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
import AsyncStorageManager from "./AsyncStorageManager";
|
import AsyncStorageManager from "./AsyncStorageManager";
|
||||||
import {DarkTheme, DefaultTheme} from 'react-native-paper';
|
import {DarkTheme, DefaultTheme} from 'react-native-paper';
|
||||||
import AprilFoolsManager from "./AprilFoolsManager";
|
import AprilFoolsManager from "./AprilFoolsManager";
|
||||||
|
import { Appearance } from 'react-native-appearance';
|
||||||
|
|
||||||
|
const colorScheme = Appearance.getColorScheme();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton class used to manage themes
|
* Singleton class used to manage themes
|
||||||
|
@ -107,7 +110,8 @@ export default class ThemeManager {
|
||||||
* @returns {boolean} Night mode state
|
* @returns {boolean} Night mode state
|
||||||
*/
|
*/
|
||||||
static getNightMode(): boolean {
|
static getNightMode(): boolean {
|
||||||
return AsyncStorageManager.getInstance().preferences.nightMode.current === '1';
|
return AsyncStorageManager.getInstance().preferences.nightMode.current === '1' ||
|
||||||
|
AsyncStorageManager.getInstance().preferences.nightModeFollowSystem.current === '1' && colorScheme === 'dark';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue