123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- /*
- * 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 <https://www.gnu.org/licenses/>.
- */
-
- import * as React from 'react';
- import {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';
-
- type PropsType = {
- navigation: StackNavigationProp<any>;
- theme: ReactNativePaper.Theme;
- };
-
- type StateType = {
- nightMode: boolean;
- nightModeFollowSystem: boolean;
- startScreenPickerSelected: string;
- selectedWash: string;
- isDebugUnlocked: boolean;
- };
-
- /**
- * Class defining the Settings screen. This screen shows controls to modify app preferences.
- */
- class SettingsScreen extends React.Component<PropsType, StateType> {
- 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 (
- <CustomSlider
- style={{flex: 1, marginHorizontal: 10, height: 50}}
- minimumValue={0}
- maximumValue={10}
- step={1}
- value={this.savedNotificationReminder}
- onValueChange={this.onProxiwashNotifPickerValueChange}
- thumbTintColor={theme.colors.primary}
- minimumTrackTintColor={theme.colors.primary}
- />
- );
- }
-
- /**
- * Returns a radio picker allowing the user to select the proxiwash
- *
- * @returns {React.Node}
- */
- getProxiwashChangePicker() {
- const {selectedWash} = this.state;
- return (
- <RadioButton.Group
- onValueChange={this.onSelectWashValueChange}
- value={selectedWash}>
- <RadioButton.Item
- label={i18n.t('screens.proxiwash.washinsa.title')}
- value="washinsa"
- />
- <RadioButton.Item
- label={i18n.t('screens.proxiwash.tripodeB.title')}
- value="tripodeB"
- />
- </RadioButton.Group>
- );
- }
-
- /**
- * Returns a picker allowing the user to select the start screen
- *
- * @returns {React.Node}
- */
- getStartScreenPicker() {
- const {startScreenPickerSelected} = this.state;
- return (
- <ToggleButton.Row
- onValueChange={this.onStartScreenPickerValueChange}
- value={startScreenPickerSelected}
- style={{marginLeft: 'auto', marginRight: 'auto'}}>
- <ToggleButton icon="account-circle" value="services" />
- <ToggleButton icon="tshirt-crew" value="proxiwash" />
- <ToggleButton icon="triangle" value="home" />
- <ToggleButton icon="calendar-range" value="planning" />
- <ToggleButton icon="clock" value="planex" />
- </ToggleButton.Row>
- );
- }
-
- /**
- * 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 (
- <List.Item
- title={title}
- description={subtitle}
- left={(props) => (
- <List.Icon color={props.color} style={props.style} icon={icon} />
- )}
- right={() => <Switch value={state} onValueChange={onPressCallback} />}
- />
- );
- }
-
- getNavigateItem(
- route: string,
- icon: string,
- title: string,
- subtitle: string,
- onLongPress?: () => void,
- ) {
- const {navigation} = this.props;
- return (
- <List.Item
- title={title}
- description={subtitle}
- onPress={() => {
- navigation.navigate(route);
- }}
- left={(props) => (
- <List.Icon color={props.color} style={props.style} icon={icon} />
- )}
- right={(props) => (
- <List.Icon
- color={props.color}
- style={props.style}
- icon="chevron-right"
- />
- )}
- 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 (
- <CollapsibleScrollView>
- <Card style={{margin: 5}}>
- <Card.Title title={i18n.t('screens.settings.generalCard')} />
- <List.Section>
- {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}
- <List.Item
- title={i18n.t('screens.settings.startScreen')}
- description={i18n.t('screens.settings.startScreenSub')}
- left={(props) => (
- <List.Icon
- color={props.color}
- style={props.style}
- icon="power"
- />
- )}
- />
- {this.getStartScreenPicker()}
- {this.getNavigateItem(
- 'dashboard-edit',
- 'view-dashboard',
- i18n.t('screens.settings.dashboard'),
- i18n.t('screens.settings.dashboardSub'),
- )}
- </List.Section>
- </Card>
- <Card style={{margin: 5}}>
- <Card.Title title="Proxiwash" />
- <List.Section>
- <List.Item
- title={i18n.t('screens.settings.proxiwashNotifReminder')}
- description={i18n.t('screens.settings.proxiwashNotifReminderSub')}
- left={(props) => (
- <List.Icon
- color={props.color}
- style={props.style}
- icon="washing-machine"
- />
- )}
- />
- <View style={{marginLeft: 30}}>
- {this.getProxiwashNotifPicker()}
- </View>
- <List.Item
- title={i18n.t('screens.settings.proxiwashChangeWash')}
- description={i18n.t('screens.settings.proxiwashChangeWashSub')}
- left={(props) => (
- <List.Icon
- color={props.color}
- style={props.style}
- icon="washing-machine"
- />
- )}
- />
- <View style={{marginLeft: 30}}>
- {this.getProxiwashChangePicker()}
- </View>
- </List.Section>
- </Card>
- <Card style={{margin: 5}}>
- <Card.Title title={i18n.t('screens.settings.information')} />
- <List.Section>
- {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'),
- )}
- </List.Section>
- </Card>
- </CollapsibleScrollView>
- );
- }
- }
-
- export default withTheme(SettingsScreen);
|