Skip to content

Commit

Permalink
RN-321 Update Settings and Notifications UX/UI Screens (mattermost#879)
Browse files Browse the repository at this point in the history
* Fix Android and iOS flow

* Own review

* RN-321 Update Settings and Notifications UX/UI Screens

* Fix style for separator in android modals

* Feedback review
  • Loading branch information
enahum authored Sep 8, 2017
1 parent 12cac73 commit adbaead
Show file tree
Hide file tree
Showing 35 changed files with 3,212 additions and 1,202 deletions.
4 changes: 2 additions & 2 deletions app/actions/views/account_notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ export function handleUpdateUserNotifyProps(notifyProps) {
const config = state.entities.general.config;
const {currentUserId} = state.entities.users;

const {interval, ...otherProps} = notifyProps;
const {interval, user_id, ...otherProps} = notifyProps;

const email = notifyProps.email;
if (config.EnableEmailBatching === 'true' && email !== 'false') {
const emailInterval = [{
user_id: notifyProps.user_id,
user_id,
category: Preferences.CATEGORY_NOTIFICATIONS,
name: Preferences.EMAIL_INTERVAL,
value: interval
Expand Down
10 changes: 10 additions & 0 deletions app/components/radio_button/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import RadioButton from './radio_button';
import RadioButtonGroup from './radio_button_group';

export {
RadioButton,
RadioButtonGroup
};
170 changes: 170 additions & 0 deletions app/components/radio_button/radio_button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import {connect} from 'react-redux';
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Animated, Text, View} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';

import {getTheme} from 'app/selectors/preferences';
import {makeStyleSheetFromTheme} from 'app/utils/theme';

const DISABLED_OPACITY = 0.26;
const DEFAULT_OPACITY = 1;

class RadioButton extends PureComponent {
static propTypes = {
label: PropTypes.string,
theme: PropTypes.object,
value: PropTypes.string,
checked: PropTypes.bool,
disabled: PropTypes.bool,
onCheck: PropTypes.func
};

constructor(props) {
super(props);
this.state = {
scaleValue: new Animated.Value(0.001),
opacityValue: new Animated.Value(0.1)
};

this.responder = {
onStartShouldSetResponder: () => true,
onResponderGrant: this.highlight,
onResponderRelease: this.handleResponderEnd,
onResponderTerminate: this.unHighlight
};
}

highlight = () => {
Animated.timing(
this.state.scaleValue,
{
toValue: 1,
duration: 150
}
).start();
Animated.timing(
this.state.opacityValue,
{
toValue: 0.1,
duration: 100
}
).start();
};

unHighlight = () => {
Animated.timing(
this.state.scaleValue,
{
toValue: 0.001,
duration: 1500
}
).start();
Animated.timing(
this.state.opacityValue,
{
toValue: 0
}
).start();
};

handleResponderEnd = () => {
const {checked, disabled, onCheck, value} = this.props;

if (!checked && !disabled && onCheck) {
onCheck(value);
}

this.unHighlight();
};

render() {
const {scaleValue, opacityValue} = this.state;
const {theme, checked, disabled} = this.props;
const styles = getStyleSheet(theme);

const color = checked ? theme.buttonBg : theme.centerChannelColor;
const opacity = disabled ? DISABLED_OPACITY : DEFAULT_OPACITY;

return (
<View
style={styles.container}
{...this.responder}
>
<Animated.View
style={[
styles.ripple,
{
transform: [
{scale: scaleValue}
],
opacity: opacityValue,
backgroundColor: color
}
]}
/>
<Icon
name={checked ? 'radio-button-checked' : 'radio-button-unchecked'}
size={24}
color={color}
style={{
opacity
}}
/>
<View style={styles.labelContainer}>
<Text
style={[
styles.label,
{opacity: disabled ? DISABLED_OPACITY : DEFAULT_OPACITY}
]}
>
{this.props.label}
</Text>
</View>
</View>
);
}
}

const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
container: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'rgba(0,0,0,0)',
marginBottom: 15
},
ripple: {
position: 'absolute',
width: 48,
height: 48,
borderRadius: 56,
top: 6
},
labelContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center'
},
label: {
color: theme.centerChannelColor,
flex: 1,
fontSize: 17,
marginLeft: 15,
textAlignVertical: 'center',
includeFontPadding: false
}
};
});

function mapStateToProps(state, ownProps) {
return {
...ownProps,
theme: getTheme(state)
};
}

export default connect(mapStateToProps)(RadioButton);
99 changes: 99 additions & 0 deletions app/components/radio_button/radio_button_group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {View} from 'react-native';
import RadioButton from './radio_button';

export default class RadioButtonGroup extends PureComponent {
static propTypes = {
children: PropTypes.node.isRequired,
name: PropTypes.string.isRequired,
value: PropTypes.string,
onSelect: PropTypes.func
};

state = {};

constructor(props) {
super(props);

if (props.value) {
this.state = {
selected: props.value
};
} else {
React.Children.map(this.props.children, (option) => {
if (option) {
const {
value,
checked
} = option.props;

if (!this.state.selected && checked) {
this.state = {
selected: value
};
}
}
});
}
}

get value() {
return this.state.selected;
}

set value(value) {
this.onChange(value);
}

onChange = (value) => {
const {onSelect} = this.props;
this.setState({
selected: value
}, () => {
if (onSelect) {
onSelect(value);
}
});
};

render = () => {
const options = React.Children.map(this.props.children, (option) => {
if (option) {
const {
value,
label,
disabled,
...other
} = option.props;

const {name} = this.props;

return (
<RadioButton
{...other}
ref={value}
name={name}
key={`${name}-${value}`}
value={value}
label={label}
disabled={disabled}
onCheck={this.onChange}
checked={this.state.selected && value === this.state.selected}
/>
);
}

return null;
}, this);

return (
<View>
{options}
</View>
);
};
}
2 changes: 1 addition & 1 deletion app/screens/about/about.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
},
scrollView: {
flex: 1,
backgroundColor: changeOpacity(theme.centerChannelColor, 0.03)
backgroundColor: changeOpacity(theme.centerChannelColor, 0.06)
},
scrollViewContent: {
paddingBottom: 30
Expand Down
Loading

0 comments on commit adbaead

Please sign in to comment.