/* * Copyright (c) 2019 - 2020 Arnaud Vergnet. * * This file is part of Campus INSAT. * * Campus INSAT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Campus INSAT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Campus INSAT. If not, see . */ import * as React from 'react'; import { StyleSheet, View } from 'react-native'; import i18n from 'i18n-js'; import { RadioButton, Card, List, Switch, ToggleButton, withTheme, } from 'react-native-paper'; import { Appearance } from 'react-native-appearance'; import { StackNavigationProp } from '@react-navigation/stack'; import ThemeManager from '../../../managers/ThemeManager'; import AsyncStorageManager from '../../../managers/AsyncStorageManager'; import CustomSlider from '../../../components/Overrides/CustomSlider'; import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView'; import GENERAL_STYLES from '../../../constants/Styles'; type PropsType = { navigation: StackNavigationProp; theme: ReactNativePaper.Theme; }; type StateType = { nightMode: boolean; nightModeFollowSystem: boolean; startScreenPickerSelected: string; selectedWash: string; isDebugUnlocked: boolean; }; const styles = StyleSheet.create({ slider: { flex: 1, marginHorizontal: 10, height: 50, }, card: { margin: 5, }, pickerContainer: { marginLeft: 30, }, }); /** * Class defining the Settings screen. This screen shows controls to modify app preferences. */ class SettingsScreen extends React.Component { savedNotificationReminder: number; /** * Loads user preferences into state */ constructor(props: PropsType) { super(props); const notifReminder = AsyncStorageManager.getString( AsyncStorageManager.PREFERENCES.proxiwashNotifications.key ); this.savedNotificationReminder = parseInt(notifReminder, 10); if (Number.isNaN(this.savedNotificationReminder)) { this.savedNotificationReminder = 0; } this.state = { nightMode: ThemeManager.getNightMode(), nightModeFollowSystem: AsyncStorageManager.getBool( AsyncStorageManager.PREFERENCES.nightModeFollowSystem.key ) && Appearance.getColorScheme() !== 'no-preference', startScreenPickerSelected: AsyncStorageManager.getString( AsyncStorageManager.PREFERENCES.defaultStartScreen.key ), selectedWash: AsyncStorageManager.getString( AsyncStorageManager.PREFERENCES.selectedWash.key ), isDebugUnlocked: AsyncStorageManager.getBool( AsyncStorageManager.PREFERENCES.debugUnlocked.key ), }; } /** * Saves the value for the proxiwash reminder notification time * * @param value The value to store */ onProxiwashNotifPickerValueChange = (value: number) => { AsyncStorageManager.set( AsyncStorageManager.PREFERENCES.proxiwashNotifications.key, value ); }; /** * Saves the value for the proxiwash reminder notification time * * @param value The value to store */ onStartScreenPickerValueChange = (value: string) => { if (value != null) { this.setState({ startScreenPickerSelected: value }); AsyncStorageManager.set( AsyncStorageManager.PREFERENCES.defaultStartScreen.key, value ); } }; /** * Returns a picker allowing the user to select the proxiwash reminder notification time * * @returns {React.Node} */ getProxiwashNotifPicker() { const { theme } = this.props; return ( ); } /** * Returns a radio picker allowing the user to select the proxiwash * * @returns {React.Node} */ getProxiwashChangePicker() { const { selectedWash } = this.state; return ( ); } /** * Returns a picker allowing the user to select the start screen * * @returns {React.Node} */ getStartScreenPicker() { const { startScreenPickerSelected } = this.state; return ( ); } /** * Toggles night mode and saves it to preferences */ onToggleNightMode = () => { const { nightMode } = this.state; ThemeManager.getInstance().setNightMode(!nightMode); this.setState({ nightMode: !nightMode }); }; onToggleNightModeFollowSystem = () => { const { nightModeFollowSystem } = this.state; const value = !nightModeFollowSystem; this.setState({ nightModeFollowSystem: value }); AsyncStorageManager.set( AsyncStorageManager.PREFERENCES.nightModeFollowSystem.key, value ); if (value) { const nightMode = Appearance.getColorScheme() === 'dark'; ThemeManager.getInstance().setNightMode(nightMode); this.setState({ nightMode }); } }; /** * Gets a list item using a checkbox control * * @param onPressCallback The callback when the checkbox state changes * @param icon The icon name to display on the list item * @param title The text to display as this list item title * @param subtitle The text to display as this list item subtitle * @param state The current state of the switch * @returns {React.Node} */ static getToggleItem( onPressCallback: () => void, icon: string, title: string, subtitle: string, state: boolean ) { return ( ( )} right={() => } /> ); } getNavigateItem( route: string, icon: string, title: string, subtitle: string, onLongPress?: () => void ) { const { navigation } = this.props; return ( { navigation.navigate(route); }} left={(props) => ( )} right={(props) => ( )} onLongPress={onLongPress} /> ); } /** * Saves the value for the proxiwash selected wash * * @param value The value to store */ onSelectWashValueChange = (value: string) => { if (value != null) { this.setState({ selectedWash: value }); AsyncStorageManager.set( AsyncStorageManager.PREFERENCES.selectedWash.key, value ); } }; /** * Unlocks debug mode and saves its state to user preferences */ unlockDebugMode = () => { this.setState({ isDebugUnlocked: true }); AsyncStorageManager.set( AsyncStorageManager.PREFERENCES.debugUnlocked.key, true ); }; render() { const { nightModeFollowSystem, nightMode, isDebugUnlocked } = this.state; return ( {Appearance.getColorScheme() !== 'no-preference' ? SettingsScreen.getToggleItem( this.onToggleNightModeFollowSystem, 'theme-light-dark', i18n.t('screens.settings.nightModeAuto'), i18n.t('screens.settings.nightModeAutoSub'), nightModeFollowSystem ) : null} {Appearance.getColorScheme() === 'no-preference' || !nightModeFollowSystem ? SettingsScreen.getToggleItem( this.onToggleNightMode, 'theme-light-dark', i18n.t('screens.settings.nightMode'), nightMode ? i18n.t('screens.settings.nightModeSubOn') : i18n.t('screens.settings.nightModeSubOff'), nightMode ) : null} ( )} /> {this.getStartScreenPicker()} {this.getNavigateItem( 'dashboard-edit', 'view-dashboard', i18n.t('screens.settings.dashboard'), i18n.t('screens.settings.dashboardSub') )} ( )} /> {this.getProxiwashNotifPicker()} ( )} /> {this.getProxiwashChangePicker()} {isDebugUnlocked ? this.getNavigateItem( 'debug', 'bug-check', i18n.t('screens.debug.title'), '' ) : null} {this.getNavigateItem( 'about', 'information', i18n.t('screens.about.title'), i18n.t('screens.about.buttonDesc'), this.unlockDebugMode )} {this.getNavigateItem( 'feedback', 'comment-quote', i18n.t('screens.feedback.homeButtonTitle'), i18n.t('screens.feedback.homeButtonSubtitle') )} ); } } export default withTheme(SettingsScreen);