forked from vergnet/application-amicale
Improved settings screen elements
This commit is contained in:
parent
517e75f4b9
commit
0b7191887d
4 changed files with 111 additions and 45 deletions
|
@ -22,6 +22,7 @@
|
||||||
"@nartc/react-native-barcode-mask": "^1.1.9",
|
"@nartc/react-native-barcode-mask": "^1.1.9",
|
||||||
"@react-native-community/masked-view": "0.1.6",
|
"@react-native-community/masked-view": "0.1.6",
|
||||||
"@react-native-community/push-notification-ios": "^1.1.1",
|
"@react-native-community/push-notification-ios": "^1.1.1",
|
||||||
|
"@react-native-community/slider": "^2.0.9",
|
||||||
"@react-navigation/bottom-tabs": "^5.1.1",
|
"@react-navigation/bottom-tabs": "^5.1.1",
|
||||||
"@react-navigation/drawer": "^5.1.1",
|
"@react-navigation/drawer": "^5.1.1",
|
||||||
"@react-navigation/native": "^5.0.9",
|
"@react-navigation/native": "^5.0.9",
|
||||||
|
|
|
@ -18,7 +18,7 @@ type Props = {
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
expanded: boolean
|
expanded: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon);
|
const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon);
|
||||||
|
@ -56,16 +56,14 @@ class AnimatedAccordion extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleAccordion = () => {
|
toggleAccordion = () => {
|
||||||
if (this.chevronRef.current != null)
|
if (this.chevronRef.current != null) {
|
||||||
this.chevronRef.current.transitionTo({rotate: this.state.expanded ? this.animStart : this.animEnd});
|
this.chevronRef.current.transitionTo({rotate: this.state.expanded ? this.animStart : this.animEnd});
|
||||||
this.setState({expanded: !this.state.expanded})
|
this.setState({expanded: !this.state.expanded})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: Props) {
|
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
|
||||||
if (nextProps.opened != null)
|
return nextState.expanded !== this.state.expanded;
|
||||||
this.state.expanded = nextProps.opened;
|
|
||||||
this.setupChevron();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
58
src/components/Overrides/CustomSlider.js
Normal file
58
src/components/Overrides/CustomSlider.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {Text, withTheme} from 'react-native-paper';
|
||||||
|
import {View} from "react-native-animatable";
|
||||||
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
|
import Slider, {SliderProps} from "@react-native-community/slider";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
theme: CustomTheme,
|
||||||
|
valueSuffix: string,
|
||||||
|
...SliderProps
|
||||||
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
currentValue: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction layer for Modalize component, using custom configuration
|
||||||
|
*
|
||||||
|
* @param props Props to pass to the element. Must specify an onRef prop to get an Modalize ref.
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
class CustomSlider extends React.Component<Props, State> {
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
valueSuffix: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
state = {
|
||||||
|
currentValue: this.props.value,
|
||||||
|
}
|
||||||
|
|
||||||
|
onValueChange = (value: number) => {
|
||||||
|
this.setState({currentValue: value});
|
||||||
|
if (this.props.onValueChange != null)
|
||||||
|
this.props.onValueChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View style={{flex: 1, flexDirection: 'row'}}>
|
||||||
|
<Text style={{marginHorizontal: 10, marginTop: 'auto', marginBottom: 'auto'}}>
|
||||||
|
{this.state.currentValue}min
|
||||||
|
</Text>
|
||||||
|
<Slider
|
||||||
|
{...this.props}
|
||||||
|
onValueChange={this.onValueChange}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withTheme(CustomSlider);
|
||||||
|
|
|
@ -1,39 +1,47 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {ScrollView} from "react-native";
|
import {ScrollView, View} from "react-native";
|
||||||
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import ThemeManager from '../../managers/ThemeManager';
|
import ThemeManager from '../../managers/ThemeManager';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
||||||
import {Card, List, Switch, ToggleButton} from 'react-native-paper';
|
import {Card, List, Switch, ToggleButton, withTheme} from 'react-native-paper';
|
||||||
import {Appearance} from "react-native-appearance";
|
import {Appearance} from "react-native-appearance";
|
||||||
import AnimatedAccordion from "../../components/Animations/AnimatedAccordion";
|
import CustomSlider from "../../components/Overrides/CustomSlider";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
theme: CustomTheme,
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
nightMode: boolean,
|
nightMode: boolean,
|
||||||
nightModeFollowSystem: boolean,
|
nightModeFollowSystem: boolean,
|
||||||
proxiwashNotifPickerSelected: string,
|
notificationReminderSelected: number,
|
||||||
startScreenPickerSelected: string,
|
startScreenPickerSelected: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining the Settings screen. This screen shows controls to modify app preferences.
|
* Class defining the Settings screen. This screen shows controls to modify app preferences.
|
||||||
*/
|
*/
|
||||||
export default class SettingsScreen extends React.Component<Props, State> {
|
class SettingsScreen extends React.Component<Props, State> {
|
||||||
state = {
|
|
||||||
nightMode: ThemeManager.getNightMode(),
|
savedNotificationReminder: number;
|
||||||
nightModeFollowSystem: AsyncStorageManager.getInstance().preferences.nightModeFollowSystem.current === '1' &&
|
|
||||||
Appearance.getColorScheme() !== 'no-preference',
|
|
||||||
proxiwashNotifPickerSelected: AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current,
|
|
||||||
startScreenPickerSelected: AsyncStorageManager.getInstance().preferences.defaultStartScreen.current,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
let notifReminder = AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current;
|
||||||
|
this.savedNotificationReminder = parseInt(notifReminder);
|
||||||
|
if (isNaN(this.savedNotificationReminder))
|
||||||
|
this.savedNotificationReminder = 0;
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
nightMode: ThemeManager.getNightMode(),
|
||||||
|
nightModeFollowSystem: AsyncStorageManager.getInstance().preferences.nightModeFollowSystem.current === '1' &&
|
||||||
|
Appearance.getColorScheme() !== 'no-preference',
|
||||||
|
notificationReminderSelected: this.savedNotificationReminder,
|
||||||
|
startScreenPickerSelected: AsyncStorageManager.getInstance().preferences.defaultStartScreen.current,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,14 +49,10 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
*
|
*
|
||||||
* @param value The value to store
|
* @param value The value to store
|
||||||
*/
|
*/
|
||||||
onProxiwashNotifPickerValueChange = (value: string) => {
|
onProxiwashNotifPickerValueChange = (value: number) => {
|
||||||
if (value != null) {
|
let key = AsyncStorageManager.getInstance().preferences.proxiwashNotifications.key;
|
||||||
let key = AsyncStorageManager.getInstance().preferences.proxiwashNotifications.key;
|
AsyncStorageManager.getInstance().savePref(key, value.toString());
|
||||||
AsyncStorageManager.getInstance().savePref(key, value);
|
this.setState({notificationReminderSelected: value})
|
||||||
this.setState({
|
|
||||||
proxiwashNotifPickerSelected: value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,15 +77,16 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
*/
|
*/
|
||||||
getProxiwashNotifPicker() {
|
getProxiwashNotifPicker() {
|
||||||
return (
|
return (
|
||||||
<ToggleButton.Row
|
<CustomSlider
|
||||||
|
style={{flex: 1, marginHorizontal: 10, height: 50}}
|
||||||
|
minimumValue={0}
|
||||||
|
maximumValue={10}
|
||||||
|
step={1}
|
||||||
|
value={this.savedNotificationReminder}
|
||||||
onValueChange={this.onProxiwashNotifPickerValueChange}
|
onValueChange={this.onProxiwashNotifPickerValueChange}
|
||||||
value={this.state.proxiwashNotifPickerSelected}
|
thumbTintColor={this.props.theme.colors.primary}
|
||||||
style={{marginLeft: 'auto', marginRight: 'auto'}}
|
minimumTrackTintColor={this.props.theme.colors.primary}
|
||||||
>
|
/>
|
||||||
<ToggleButton icon="close" value="never"/>
|
|
||||||
<ToggleButton icon="numeric-2" value="2"/>
|
|
||||||
<ToggleButton icon="numeric-5" value="5"/>
|
|
||||||
</ToggleButton.Row>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +138,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
* @param icon The icon name to display on the list item
|
* @param icon The icon name to display on the list item
|
||||||
* @param title The text to display as this list item title
|
* @param title The text to display as this list item title
|
||||||
* @param subtitle The text to display as this list item subtitle
|
* @param subtitle The text to display as this list item subtitle
|
||||||
|
* @param state The current state of the switch
|
||||||
* @returns {React.Node}
|
* @returns {React.Node}
|
||||||
*/
|
*/
|
||||||
getToggleItem(onPressCallback: Function, icon: string, title: string, subtitle: string, state: boolean) {
|
getToggleItem(onPressCallback: Function, icon: string, title: string, subtitle: string, state: boolean) {
|
||||||
|
@ -141,7 +147,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
title={title}
|
title={title}
|
||||||
description={subtitle}
|
description={subtitle}
|
||||||
left={props => <List.Icon {...props} icon={icon}/>}
|
left={props => <List.Icon {...props} icon={icon}/>}
|
||||||
right={props =>
|
right={() =>
|
||||||
<Switch
|
<Switch
|
||||||
value={state}
|
value={state}
|
||||||
onValueChange={onPressCallback}
|
onValueChange={onPressCallback}
|
||||||
|
@ -177,28 +183,31 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
this.state.nightMode
|
this.state.nightMode
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
<AnimatedAccordion
|
<List.Item
|
||||||
title={i18n.t('settingsScreen.startScreen')}
|
title={i18n.t('settingsScreen.startScreen')}
|
||||||
subtitle={i18n.t('settingsScreen.startScreenSub')}
|
subtitle={i18n.t('settingsScreen.startScreenSub')}
|
||||||
left={props => <List.Icon {...props} icon="power"/>}
|
left={props => <List.Icon {...props} icon="power"/>}
|
||||||
>
|
/>
|
||||||
{this.getStartScreenPicker()}
|
{this.getStartScreenPicker()}
|
||||||
</AnimatedAccordion>
|
|
||||||
</List.Section>
|
</List.Section>
|
||||||
</Card>
|
</Card>
|
||||||
<Card style={{margin: 5}}>
|
<Card style={{margin: 5}}>
|
||||||
<Card.Title title="Proxiwash"/>
|
<Card.Title title="Proxiwash"/>
|
||||||
<List.Section>
|
<List.Section>
|
||||||
<AnimatedAccordion
|
<List.Item
|
||||||
title={i18n.t('settingsScreen.proxiwashNotifReminder')}
|
title={i18n.t('settingsScreen.proxiwashNotifReminder')}
|
||||||
description={i18n.t('settingsScreen.proxiwashNotifReminderSub')}
|
description={i18n.t('settingsScreen.proxiwashNotifReminderSub')}
|
||||||
left={props => <List.Icon {...props} icon="washing-machine"/>}
|
left={props => <List.Icon {...props} icon="washing-machine"/>}
|
||||||
>
|
opened={true}
|
||||||
|
/>
|
||||||
|
<View style={{marginLeft: 30}}>
|
||||||
{this.getProxiwashNotifPicker()}
|
{this.getProxiwashNotifPicker()}
|
||||||
</AnimatedAccordion>
|
</View>
|
||||||
</List.Section>
|
</List.Section>
|
||||||
</Card>
|
</Card>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withTheme(SettingsScreen);
|
||||||
|
|
Loading…
Reference in a new issue