mattermost-mobile/app/screens/theme/theme.js
Chris Duarte 7c711caf2d Theme selection screen (#2320)
* Theme selection screen (initial commit)

PR Review changes

Add custom theme option for users who are already using a custom theme

Fix for limited allowed themes

Selected item case fix

Memoized available themes request, other optimizations

updated snapshots

* Custom theme option changes - title. spacing, save option on state for life-cycle of screen
2018-11-23 14:49:28 -03:00

134 lines
4.2 KiB
JavaScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {View, FlatList} from 'react-native';
import PropTypes from 'prop-types';
import {intlShape} from 'react-intl';
import StatusBar from 'app/components/status_bar';
import Section from 'app/screens/settings/section';
import SectionItem from 'app/screens/settings/section_item';
import FormattedText from 'app/components/formatted_text';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import Preferences from 'mattermost-redux/constants/preferences';
export default class Theme extends React.PureComponent {
static propTypes = {
teamId: PropTypes.string.isRequired,
theme: PropTypes.object.isRequired,
userId: PropTypes.string.isRequired,
actions: PropTypes.shape({
savePreferences: PropTypes.func.isRequired,
}).isRequired,
allowedThemes: PropTypes.arrayOf(PropTypes.object),
customTheme: PropTypes.object,
};
static contextTypes = {
intl: intlShape.isRequired,
};
state = {
customTheme: null,
};
static getDerivedStateFromProps(props, state) {
if (!state.customTheme && props.customTheme) {
return {
customTheme: props.customTheme,
};
}
return null;
}
setTheme = (key) => {
const {userId, teamId, actions: {savePreferences}, allowedThemes} = this.props;
const {customTheme} = this.state;
const selectedTheme = allowedThemes.concat(customTheme).find((theme) => theme.key === key);
savePreferences(userId, [{
user_id: userId,
category: Preferences.CATEGORY_THEME,
name: teamId,
value: JSON.stringify(selectedTheme),
}]);
}
renderThemeRow = ({item, title}) => {
const {theme} = this.props;
const style = getStyleSheet(theme);
return (
<React.Fragment>
<SectionItem
label={(
<FormattedText
id={`user.settings.display.${item.type}`}
defaultMessage={title || item.type}
/>
)}
action={this.setTheme}
actionType='select'
actionValue={item.key}
selected={item.type.toLowerCase() === theme.type.toLowerCase()}
theme={theme}
/>
<View style={style.divider}/>
</React.Fragment>
);
};
keyExtractor = (item) => item.key;
render() {
const {theme, allowedThemes} = this.props;
const {customTheme} = this.state;
const style = getStyleSheet(theme);
return (
<View style={style.container}>
<StatusBar/>
<View style={style.wrapper}>
<Section
disableHeader={true}
theme={theme}
>
<FlatList
data={allowedThemes}
renderItem={this.renderThemeRow}
keyExtractor={this.keyExtractor}
/>
</Section>
{customTheme &&
<Section
disableHeader={true}
theme={theme}
>
{this.renderThemeRow({item: customTheme, title: 'Custom'})}
</Section>
}
</View>
</View>
);
}
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
container: {
flex: 1,
backgroundColor: theme.centerChannelBg,
},
wrapper: {
backgroundColor: changeOpacity(theme.centerChannelColor, 0.06),
flex: 1,
paddingTop: 35,
},
divider: {
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1),
height: 1,
},
};
});