Commit cfee4808 authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Merge branch 'feature/settings-screen' into 'master'

Added settings screen for push notification categories

Closes #45

See merge request !179
parents fe2d8c7d 1ebb16b8
......@@ -26,6 +26,10 @@ const sceneToTitle = (scene, t) => {
return t('Profile');
case 'registration':
return t('Registration');
case 'settings':
return t('Settings');
case 'pushNotificationsSettings':
return t('Notifications');
default:
return 'ThaliApp';
}
......
import React, { Component } from 'react';
import { Switch, Text, View } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import styles from './style/NotificationsSection';
import Colors from '../../style/Colors';
import { notificationsSettingsActions } from '../../../actions/settings';
import CardSection from '../../components/cardSection/CardSection';
const GENERAL_KEY = 'general';
class NotificationsSection extends Component {
constructor(props) {
super(props);
this.state = {};
}
static getDerivedStateFromProps = (props) => {
if (props.status !== 'success') {
return null;
}
const newState = {};
for (let i = 0; i < props.categoryList.length; i += 1) {
if (props.categoryList[i].key === GENERAL_KEY) {
newState[props.categoryList[i].key] = true;
} else {
newState[props.categoryList[i].key] = props.categoryList[i].enabled;
}
}
return newState;
};
updateField = (key, value) => {
const update = {};
update[key] = value;
this.setState(update, () => {
const categories = Object.keys(this.state).filter(k => this.state[k]);
this.props.saveCategories(categories);
});
};
render() {
const { status, categoryList, t } = this.props;
let content = (
<Text style={styles.emptyText}>
{t('Notifications settings could not be loaded.')}
</Text>
);
if (status === 'success') {
content = categoryList.map((category, i) => (
<View
style={[styles.categoryContainer, i !== 0 && styles.borderTop]}
key={category.key}
>
<Text
style={styles.label}
>
{category.name}
{' '}
{category.key === GENERAL_KEY && this.props.t('(required)')}
</Text>
<Switch
value={this.state[category.key]}
onValueChange={value => this.updateField(category.key, value)}
onTintColor={Colors.magenta}
thumbTintColor={this.state[category.key]
? Colors.darkMagenta : Colors.gray}
disabled={category.key === GENERAL_KEY}
/>
</View>
));
}
return (
<CardSection sectionHeader={t('Notifications')}>
{content}
</CardSection>
);
}
}
NotificationsSection.propTypes = {
categoryList: PropTypes.arrayOf(PropTypes.shape({
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
enabled: PropTypes.bool.isRequired,
})).isRequired,
status: PropTypes.string.isRequired,
saveCategories: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({
categoryList: state.settings.pushNotifications.categoryList,
status: state.settings.pushNotifications.status,
});
const mapDispatchToProps = dispatch => ({
saveCategories: catList => dispatch(notificationsSettingsActions.saveCategories(catList)),
});
export default connect(mapStateToProps, mapDispatchToProps)(translate('screens/settings/PushNotifications')(NotificationsSection));
import React from 'react';
import { ScrollView, View } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import styles from './style/Settings';
import { settingsActions } from '../../../actions/settings';
import LoadingScreen from '../../components/loadingScreen/LoadingScreen';
import NotificationsSection from './NotificationsSection';
class Settings extends React.Component {
componentDidMount() {
this.props.init();
}
render() {
const { loading } = this.props;
if (loading) {
return <LoadingScreen />;
}
return (
<View style={styles.container}>
<ScrollView
style={styles.container}
>
<View style={styles.content}>
<NotificationsSection />
</View>
</ScrollView>
</View>
);
}
}
Settings.propTypes = {
init: PropTypes.func.isRequired,
loading: PropTypes.bool.isRequired,
};
const mapStateToProps = state => ({
loading: state.settings.loading,
});
const mapDispatchToProps = dispatch => ({
init: () => dispatch(settingsActions.initStart()),
});
export default connect(mapStateToProps, mapDispatchToProps)(Settings);
import StyleSheet from '../../../style/StyleSheet';
import Colors from '../../../style/Colors';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.background,
},
categoryContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 16,
},
borderTop: {
borderTopColor: Colors.dividerGrey,
borderTopWidth: 1,
},
label: {
color: Colors.textColour,
android: {
fontFamily: 'sans-serif-medium',
},
ios: {
fontFamily: 'System',
fontWeight: '600',
},
},
emptyText: {
padding: 16,
},
});
export default styles;
import Colors from '../../../style/Colors';
import Stylesheet from '../../../style/StyleSheet';
const styles = Stylesheet.create({
container: {
flex: 1,
backgroundColor: Colors.background,
},
content: {
flex: 1,
padding: 8,
backgroundColor: Colors.background,
},
});
export default styles;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment