Apply setNavigatorStyles to all navigation components (#3122)

This commit is contained in:
Mattermost Build 2019-08-14 20:06:57 +02:00 committed by Saturnino Abril
parent 90dba40a92
commit c1957ac6a0
10 changed files with 79 additions and 29 deletions

View file

@ -291,7 +291,11 @@ export function dismissModal(options = {}) {
return () => {
const componentId = EphemeralStore.getNavigationTopComponentId();
Navigation.dismissModal(componentId, options);
Navigation.dismissModal(componentId, options).catch(() => {
// RNN returns a promise rejection if there is no modal to
// dismiss. We'll do nothing in this case but we will catch
// the rejection here so that the caller doesn't have to.
});
};
}

View file

@ -3,7 +3,6 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Navigation} from 'react-native-navigation';
import {intlShape} from 'react-intl';
import {
Platform,
@ -20,7 +19,6 @@ import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
export default class DisplaySettings extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
applyTheme: PropTypes.func.isRequired,
goToScreen: PropTypes.func.isRequired,
}).isRequired,
componentId: PropTypes.string,
@ -37,15 +35,6 @@ export default class DisplaySettings extends PureComponent {
showClockDisplaySettings: false,
};
componentDidMount() {
this.navigationEventListener = Navigation.events().bindComponent(this);
}
componentDidAppear() {
const {actions, componentId} = this.props;
actions.applyTheme(componentId);
}
closeClockDisplaySettings = () => {
this.setState({showClockDisplaySettings: false});
};

View file

@ -16,7 +16,6 @@ jest.mock('react-intl');
describe('DisplaySettings', () => {
const baseProps = {
actions: {
applyTheme: jest.fn(),
goToScreen: jest.fn(),
},
theme: Preferences.THEMES.default,

View file

@ -7,7 +7,7 @@ import {connect} from 'react-redux';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
import {applyTheme, goToScreen} from 'app/actions/navigation';
import {goToScreen} from 'app/actions/navigation';
import {getAllowedThemes} from 'app/selectors/theme';
import {isThemeSwitchingEnabled} from 'app/utils/theme';
@ -28,7 +28,6 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
goToScreen,
applyTheme,
}, dispatch),
};
}

View file

@ -9,7 +9,7 @@ import {getCurrentUrl, getConfig} from 'mattermost-redux/selectors/entities/gene
import {getJoinableTeams} from 'mattermost-redux/selectors/entities/teams';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {applyTheme, goToScreen, dismissModal} from 'app/actions/navigation';
import {goToScreen, dismissModal} from 'app/actions/navigation';
import {purgeOfflineStore} from 'app/actions/views/root';
import {removeProtocol} from 'app/utils/url';
@ -32,7 +32,6 @@ function mapStateToProps(state) {
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
applyTheme,
clearErrors,
purgeOfflineStore,
goToScreen,

View file

@ -25,7 +25,6 @@ import LocalConfig from 'assets/config';
class Settings extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
applyTheme: PropTypes.func.isRequired,
clearErrors: PropTypes.func.isRequired,
purgeOfflineStore: PropTypes.func.isRequired,
goToScreen: PropTypes.func.isRequired,
@ -51,11 +50,6 @@ class Settings extends PureComponent {
this.navigationEventListener = Navigation.events().bindComponent(this);
}
componentDidAppear() {
const {actions, componentId} = this.props;
actions.applyTheme(componentId, true);
}
navigationButtonPressed({buttonId}) {
if (buttonId === 'close-settings') {
this.props.actions.dismissModal();

View file

@ -6,14 +6,16 @@ import {Text, View} from 'react-native';
import PropTypes from 'prop-types';
import {intlShape} from 'react-intl';
import Preferences from 'mattermost-redux/constants/preferences';
import StatusBar from 'app/components/status_bar';
import Section from 'app/screens/settings/section';
import SectionItem from 'app/screens/settings/section_item';
import ThemeTile from './theme_tile';
import FormattedText from 'app/components/formatted_text';
import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme';
import Preferences from 'mattermost-redux/constants/preferences';
import EphemeralStore from 'app/store/ephemeral_store';
import ThemeTile from './theme_tile';
const thumbnailImages = {
default: require('assets/images/themes/mattermost.png'),
@ -56,7 +58,9 @@ export default class Theme extends React.PureComponent {
componentDidUpdate(prevProps) {
if (prevProps.theme !== this.props.theme) {
setNavigatorStyles(this.props.componentId, this.props.theme);
EphemeralStore.allNavigationComponentIds.forEach((componentId) => {
setNavigatorStyles(componentId, this.props.theme);
});
}
}

View file

@ -3,14 +3,23 @@
import React from 'react';
import {shallow} from 'enzyme';
import {Navigation} from 'react-native-navigation';
import Preferences from 'mattermost-redux/constants/preferences';
import EphemeralStore from 'app/store/ephemeral_store';
import Theme from './theme';
import ThemeTile from './theme_tile';
jest.mock('react-intl');
jest.mock('react-native-navigation', () => ({
Navigation: {
mergeOptions: jest.fn(),
},
}));
const allowedThemes = [
{
type: 'Mattermost',
@ -143,4 +152,43 @@ describe('Theme', () => {
expect(wrapper.getElement()).toMatchSnapshot();
expect(wrapper.find(ThemeTile)).toHaveLength(4);
});
test('should call Navigation.mergeOptions on all navigation components when theme changes', () => {
const componentIds = ['component-1', 'component-2', 'component-3'];
componentIds.forEach((componentId) => {
EphemeralStore.addNavigationComponentId(componentId);
});
const wrapper = shallow(
<Theme {...baseProps}/>,
);
const newTheme = allowedThemes[1];
wrapper.setProps({theme: newTheme});
const options = {
topBar: {
backButton: {
color: newTheme.sidebarHeaderTextColor,
},
background: {
color: newTheme.sidebarHeaderBg,
},
title: {
color: newTheme.sidebarHeaderTextColor,
},
leftButtonColor: newTheme.sidebarHeaderTextColor,
rightButtonColor: newTheme.sidebarHeaderTextColor,
},
layout: {
backgroundColor: newTheme.centerChannelBg,
},
};
expect(Navigation.mergeOptions.mock.calls).toEqual([
[componentIds[2], options],
[componentIds[1], options],
[componentIds[0], options],
]);
});
});

View file

@ -7,20 +7,31 @@ class EphemeralStore {
this.appStartedFromPushNotification = false;
this.deviceToken = null;
this.navigationComponentIdStack = [];
this.allNavigationComponentIds = [];
this.currentServerUrl = null;
}
getNavigationTopComponentId = () => this.navigationComponentIdStack[0];
getNavigationComponentIds = () => this.navigationComponentIdStack;
addNavigationComponentId = (componentId) => {
this.addToNavigationComponentIdStack(componentId);
this.addToAllNavigationComponentIds(componentId);
};
addToNavigationComponentIdStack = (componentId) => {
const index = this.navigationComponentIdStack.indexOf(componentId);
if (index > 0) {
this.navigationComponentIdStack.slice(index, 1);
}
this.navigationComponentIdStack.unshift(componentId);
};
}
addToAllNavigationComponentIds = (componentId) => {
if (!this.allNavigationComponentIds.includes(componentId)) {
this.allNavigationComponentIds.unshift(componentId);
}
}
removeNavigationComponentId = (componentId) => {
const index = this.navigationComponentIdStack.indexOf(componentId);

View file

@ -31,6 +31,9 @@ export function setNavigatorStyles(componentId, theme) {
},
leftButtonColor: theme.sidebarHeaderTextColor,
rightButtonColor: theme.sidebarHeaderTextColor,
backButton: {
color: theme.sidebarHeaderTextColor,
},
},
layout: {
backgroundColor: theme.centerChannelBg,