MM-17424 Setting to enable/disable fixed sidebar (#3060)
This commit is contained in:
parent
94b48813f9
commit
d230bdac1e
31 changed files with 679 additions and 19 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ChannelSidebar should match, full snapshot 1`] = `
|
||||
exports[`MainSidebar should match, full snapshot 1`] = `
|
||||
<DrawerLayout
|
||||
drawerPosition="left"
|
||||
drawerWidth={-30}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
View,
|
||||
} from 'react-native';
|
||||
import {intlShape} from 'react-intl';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
|
||||
import {General, WebsocketEvents} from 'mattermost-redux/constants';
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
|
@ -79,9 +80,11 @@ export default class ChannelSidebar extends Component {
|
|||
this.mounted = true;
|
||||
this.props.actions.getTeams();
|
||||
this.handleDimensions();
|
||||
this.handlePermanentSidebar();
|
||||
EventEmitter.on('close_channel_drawer', this.closeChannelDrawer);
|
||||
EventEmitter.on('renderDrawer', this.handleShowDrawerContent);
|
||||
EventEmitter.on(WebsocketEvents.CHANNEL_UPDATED, this.handleUpdateTitle);
|
||||
EventEmitter.on(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, this.handlePermanentSidebar);
|
||||
BackHandler.addEventListener('hardwareBackPress', this.handleAndroidBack);
|
||||
Dimensions.addEventListener('change', this.handleDimensions);
|
||||
}
|
||||
|
|
@ -103,7 +106,7 @@ export default class ChannelSidebar extends Component {
|
|||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const {currentTeamId, deviceWidth, isLandscape, teamsCount} = this.props;
|
||||
const {openDrawerOffset, isSplitView, show, searching} = this.state;
|
||||
const {openDrawerOffset, isSplitView, permanentSidebar, show, searching} = this.state;
|
||||
|
||||
if (nextState.openDrawerOffset !== openDrawerOffset || nextState.show !== show || nextState.searching !== searching) {
|
||||
return true;
|
||||
|
|
@ -112,7 +115,8 @@ export default class ChannelSidebar extends Component {
|
|||
return nextProps.currentTeamId !== currentTeamId ||
|
||||
nextProps.isLandscape !== isLandscape || nextProps.deviceWidth !== deviceWidth ||
|
||||
nextProps.teamsCount !== teamsCount ||
|
||||
nextState.isSplitView !== isSplitView;
|
||||
nextState.isSplitView !== isSplitView ||
|
||||
nextState.permanentSidebar !== permanentSidebar;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
@ -120,6 +124,7 @@ export default class ChannelSidebar extends Component {
|
|||
EventEmitter.off('close_channel_drawer', this.closeChannelDrawer);
|
||||
EventEmitter.off(WebsocketEvents.CHANNEL_UPDATED, this.handleUpdateTitle);
|
||||
EventEmitter.off('renderDrawer', this.handleShowDrawerContent);
|
||||
EventEmitter.off(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, this.handlePermanentSidebar);
|
||||
BackHandler.removeEventListener('hardwareBackPress', this.handleAndroidBack);
|
||||
Dimensions.addEventListener('change', this.handleDimensions);
|
||||
}
|
||||
|
|
@ -142,6 +147,13 @@ export default class ChannelSidebar extends Component {
|
|||
}
|
||||
};
|
||||
|
||||
handlePermanentSidebar = async () => {
|
||||
if (DeviceTypes.IS_TABLET && this.mounted) {
|
||||
const enabled = await AsyncStorage.getItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS);
|
||||
this.setState({permanentSidebar: enabled === 'true'});
|
||||
}
|
||||
};
|
||||
|
||||
handleShowDrawerContent = () => {
|
||||
requestAnimationFrame(() => this.setState({show: true}));
|
||||
};
|
||||
|
|
@ -396,7 +408,7 @@ export default class ChannelSidebar extends Component {
|
|||
render() {
|
||||
const {children, deviceWidth} = this.props;
|
||||
const {openDrawerOffset} = this.state;
|
||||
const isTablet = DeviceTypes.IS_TABLET && !this.state.isSplitView;
|
||||
const isTablet = DeviceTypes.IS_TABLET && !this.state.isSplitView && this.state.permanentSidebar;
|
||||
const drawerWidth = DeviceTypes.IS_TABLET ? TABLET_WIDTH : (deviceWidth - openDrawerOffset);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ import {shallow} from 'enzyme';
|
|||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import ChannelSidebar from './main_sidebar';
|
||||
import {DeviceTypes} from 'app/constants';
|
||||
|
||||
import MainSidebar from './main_sidebar';
|
||||
|
||||
jest.mock('react-intl');
|
||||
|
||||
describe('ChannelSidebar', () => {
|
||||
describe('MainSidebar', () => {
|
||||
const baseProps = {
|
||||
actions: {
|
||||
getTeams: jest.fn(),
|
||||
|
|
@ -30,9 +32,30 @@ describe('ChannelSidebar', () => {
|
|||
|
||||
test('should match, full snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
<ChannelSidebar {...baseProps}/>
|
||||
<MainSidebar {...baseProps}/>
|
||||
);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should not set the permanentSidebar state if not Tablet', () => {
|
||||
const wrapper = shallow(
|
||||
<MainSidebar {...baseProps}/>
|
||||
);
|
||||
|
||||
wrapper.instance().handlePermanentSidebar();
|
||||
expect(wrapper.state('permanentSidebar')).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should set the permanentSidebar state if Tablet', async () => {
|
||||
const wrapper = shallow(
|
||||
<MainSidebar {...baseProps}/>
|
||||
);
|
||||
|
||||
DeviceTypes.IS_TABLET = true;
|
||||
|
||||
await wrapper.instance().handlePermanentSidebar();
|
||||
|
||||
expect(wrapper.state('permanentSidebar')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,4 +20,5 @@ export default {
|
|||
IS_IPHONE_X: DeviceInfo.getModel().includes('iPhone X'),
|
||||
IS_TABLET: DeviceInfo.isTablet(),
|
||||
VIDEOS_PATH: `${RNFetchBlobFS.dirs.CacheDir}/Videos`,
|
||||
PERMANENT_SIDEBAR_SETTINGS: '@PERMANENT_SIDEBAR_SETTINGS',
|
||||
};
|
||||
|
|
|
|||
13
app/init/device.js
Normal file
13
app/init/device.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import {DeviceTypes} from 'app/constants';
|
||||
|
||||
if (DeviceTypes.IS_TABLET) {
|
||||
AsyncStorage.getItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS).then((value) => {
|
||||
if (!value) {
|
||||
AsyncStorage.setItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, 'true');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import {setDeepLinkURL} from 'app/actions/views/root';
|
|||
import initialState from 'app/initial_state';
|
||||
import {getAppCredentials} from 'app/init/credentials';
|
||||
import emmProvider from 'app/init/emm_provider';
|
||||
import 'app/init/device';
|
||||
import 'app/init/fetch';
|
||||
import globalEventHandler from 'app/init/global_event_handler';
|
||||
import {registerScreens} from 'app/screens';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ChannelNavBar should match, full snapshot 1`] = `
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#1153ab",
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-start",
|
||||
"width": "100%",
|
||||
"zIndex": 10,
|
||||
},
|
||||
Object {
|
||||
"paddingHorizontal": 0,
|
||||
},
|
||||
Object {
|
||||
"height": 44,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<Connect(ChannelDrawerButton)
|
||||
openDrawer={[MockFunction]}
|
||||
visible={true}
|
||||
/>
|
||||
<Connect(ChannelTitle)
|
||||
canHaveSubtitle={true}
|
||||
onPress={[MockFunction]}
|
||||
/>
|
||||
<Connect(ChannelSearchButton)
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<Connect(SettingDrawerButton)
|
||||
openDrawer={[MockFunction]}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
|
@ -4,6 +4,9 @@
|
|||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Dimensions, Platform, View} from 'react-native';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
||||
import {DeviceTypes, ViewTypes} from 'app/constants';
|
||||
import mattermostManaged from 'app/mattermost_managed';
|
||||
|
|
@ -38,12 +41,15 @@ export default class ChannelNavBar extends PureComponent {
|
|||
componentDidMount() {
|
||||
this.mounted = true;
|
||||
this.handleDimensions();
|
||||
this.handlePermanentSidebar();
|
||||
Dimensions.addEventListener('change', this.handleDimensions);
|
||||
EventEmitter.on(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, this.handlePermanentSidebar);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.mounted = false;
|
||||
Dimensions.removeEventListener('change', this.handleDimensions);
|
||||
EventEmitter.off(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, this.handlePermanentSidebar);
|
||||
}
|
||||
|
||||
handleDimensions = () => {
|
||||
|
|
@ -55,6 +61,14 @@ export default class ChannelNavBar extends PureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
handlePermanentSidebar = () => {
|
||||
if (DeviceTypes.IS_TABLET && this.mounted) {
|
||||
AsyncStorage.getItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS).then((enabled) => {
|
||||
this.setState({permanentSidebar: enabled === 'true'});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {isLandscape, onPress, theme} = this.props;
|
||||
const {openChannelDrawer, openSettingsDrawer} = this.props;
|
||||
|
|
@ -87,7 +101,7 @@ export default class ChannelNavBar extends PureComponent {
|
|||
}
|
||||
|
||||
let drawerButtonVisible = false;
|
||||
if (!DeviceTypes.IS_TABLET || this.state.isSplitView) {
|
||||
if (!DeviceTypes.IS_TABLET || this.state.isSplitView || !this.state.permanentSidebar) {
|
||||
drawerButtonVisible = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
52
app/screens/channel/channel_nav_bar/channel_nav_bar.test.js
Normal file
52
app/screens/channel/channel_nav_bar/channel_nav_bar.test.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import {DeviceTypes} from 'app/constants';
|
||||
|
||||
import ChannelNavBar from './channel_nav_bar';
|
||||
|
||||
jest.mock('react-intl');
|
||||
|
||||
describe('ChannelNavBar', () => {
|
||||
const baseProps = {
|
||||
isLandscape: false,
|
||||
openChannelDrawer: jest.fn(),
|
||||
openSettingsDrawer: jest.fn(),
|
||||
onPress: jest.fn(),
|
||||
theme: Preferences.THEMES.default,
|
||||
};
|
||||
|
||||
test('should match, full snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
<ChannelNavBar {...baseProps}/>
|
||||
);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should not set the permanentSidebar state if not Tablet', () => {
|
||||
const wrapper = shallow(
|
||||
<ChannelNavBar {...baseProps}/>
|
||||
);
|
||||
|
||||
wrapper.instance().handlePermanentSidebar();
|
||||
expect(wrapper.state('permanentSidebar')).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should set the permanentSidebar state if Tablet', async () => {
|
||||
const wrapper = shallow(
|
||||
<ChannelNavBar {...baseProps}/>
|
||||
);
|
||||
|
||||
DeviceTypes.IS_TABLET = true;
|
||||
|
||||
await wrapper.instance().handlePermanentSidebar();
|
||||
|
||||
expect(wrapper.state('permanentSidebar')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -28,7 +28,7 @@ export function registerScreens(store, Provider) {
|
|||
Navigation.registerComponent('ChannelMembers', () => wrapper(require('app/screens/channel_members').default), () => require('app/screens/channel_members').default);
|
||||
Navigation.registerComponent('ChannelPeek', () => wrapper(require('app/screens/channel_peek').default), () => require('app/screens/channel_peek').default);
|
||||
Navigation.registerComponent('ClientUpgrade', () => wrapper(require('app/screens/client_upgrade').default), () => require('app/screens/client_upgrade').default);
|
||||
Navigation.registerComponent('ClockDisplay', () => wrapper(require('app/screens/clock_display').default), () => require('app/screens/clock_display').default);
|
||||
Navigation.registerComponent('ClockDisplaySettings', () => wrapper(require('app/screens/settings/clock_display').default), () => require('app/screens/settings/clock_display').default);
|
||||
Navigation.registerComponent('Code', () => wrapper(require('app/screens/code').default), () => require('app/screens/code').default);
|
||||
Navigation.registerComponent('CreateChannel', () => wrapper(require('app/screens/create_channel').default), () => require('app/screens/create_channel').default);
|
||||
Navigation.registerComponent('DisplaySettings', () => wrapper(require('app/screens/settings/display_settings').default), () => require('app/screens/settings/display_settings').default);
|
||||
|
|
@ -64,16 +64,17 @@ export function registerScreens(store, Provider) {
|
|||
Navigation.registerComponent('SelectorScreen', () => wrapper(require('app/screens/selector_screen').default), () => require('app/screens/selector_screen').default);
|
||||
Navigation.registerComponent('SelectServer', () => wrapper(SelectServer), () => SelectServer);
|
||||
Navigation.registerComponent('SelectTeam', () => wrapper(require('app/screens/select_team').default), () => require('app/screens/select_team').default);
|
||||
Navigation.registerComponent('SelectTimezone', () => wrapper(require('app/screens/timezone/select_timezone').default), () => require('app/screens/timezone/select_timezone').default);
|
||||
Navigation.registerComponent('SelectTimezone', () => wrapper(require('app/screens/settings/timezone/select_timezone').default), () => require('app/screens/settings/timezone/select_timezone').default);
|
||||
Navigation.registerComponent('Settings', () => wrapper(require('app/screens/settings/general').default), () => require('app/screens/settings/general').default);
|
||||
Navigation.registerComponent('SidebarSettings', () => wrapper(require('app/screens//settings/sidebar').default), () => require('app/screens/settings/sidebar').default);
|
||||
Navigation.registerComponent('SSO', () => wrapper(require('app/screens/sso').default), () => require('app/screens/sso').default);
|
||||
Navigation.registerComponent('Table', () => wrapper(require('app/screens/table').default), () => require('app/screens/table').default);
|
||||
Navigation.registerComponent('TableImage', () => wrapper(require('app/screens/table_image').default), () => require('app/screens/table_image').default);
|
||||
Navigation.registerComponent('TermsOfService', () => wrapper(require('app/screens/terms_of_service').default), () => require('app/screens/terms_of_service').default);
|
||||
Navigation.registerComponent('TextPreview', () => wrapper(require('app/screens/text_preview').default), () => require('app/screens/text_preview').default);
|
||||
Navigation.registerComponent('ThemeSettings', () => wrapper(require('app/screens/theme').default), () => require('app/screens/theme').default);
|
||||
Navigation.registerComponent('ThemeSettings', () => wrapper(require('app/screens/settings/theme').default), () => require('app/screens/settings/theme').default);
|
||||
Navigation.registerComponent('Thread', () => wrapper(require('app/screens/thread').default), () => require('app/screens/thread').default);
|
||||
Navigation.registerComponent('TimezoneSettings', () => wrapper(require('app/screens/timezone').default), () => require('app/screens/timezone').default);
|
||||
Navigation.registerComponent('TimezoneSettings', () => wrapper(require('app/screens/settings/timezone').default), () => require('app/screens/settings/timezone').default);
|
||||
Navigation.registerComponent('ErrorTeamsList', () => wrapper(require('app/screens/error_teams_list').default), () => require('app/screens/error_teams_list').default);
|
||||
Navigation.registerComponent('UserProfile', () => wrapper(require('app/screens/user_profile').default), () => require('app/screens/user_profile').default);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import ClockDisplayBase from './clock_display_base';
|
|||
export default class ClockDisplay extends ClockDisplayBase {
|
||||
static propTypes = {
|
||||
showModal: PropTypes.bool.isRequired,
|
||||
militaryTime: PropTypes.bool.isRequired,
|
||||
militaryTime: PropTypes.string.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
|
@ -76,3 +76,118 @@ exports[`DisplaySettings should match snapshot 1`] = `
|
|||
</View>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`DisplaySettings should match snapshot on Tablet devices 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Connect(StatusBar) />
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.06)",
|
||||
"flex": 1,
|
||||
"paddingTop": 35,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.1)",
|
||||
"height": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<SettingsItem
|
||||
defaultMessage="Sidebar"
|
||||
i18nId="mobile.display_settings.sidebar"
|
||||
iconName="columns"
|
||||
iconType="fontawesome"
|
||||
isDestructor={false}
|
||||
onPress={[Function]}
|
||||
separator={true}
|
||||
showArrow={false}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<SettingsItem
|
||||
defaultMessage="Clock Display"
|
||||
i18nId="mobile.advanced_settings.clockDisplay"
|
||||
iconName="ios-time"
|
||||
iconType="ion"
|
||||
isDestructor={false}
|
||||
onPress={[Function]}
|
||||
separator={false}
|
||||
showArrow={false}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.1)",
|
||||
"height": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import {
|
|||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import SettingsItem from 'app/screens/settings/settings_item';
|
||||
import {DeviceTypes} from 'app/constants';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import ClockDisplay from 'app/screens/settings/clock_display';
|
||||
import SettingsItem from 'app/screens/settings/settings_item';
|
||||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
import ClockDisplay from 'app/screens/clock_display';
|
||||
|
||||
export default class DisplaySettings extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
|
|
@ -53,6 +53,15 @@ export default class DisplaySettings extends PureComponent {
|
|||
this.setState({showClockDisplaySettings: true});
|
||||
});
|
||||
|
||||
goToSidebarSettings = preventDoubleTap(() => {
|
||||
const {actions, theme} = this.props;
|
||||
const {intl} = this.context;
|
||||
const screen = 'SidebarSettings';
|
||||
const title = intl.formatMessage({id: 'mobile.display_settings.sidebar', defaultMessage: 'Sidebar'});
|
||||
|
||||
actions.goToScreen(screen, title, {theme});
|
||||
});
|
||||
|
||||
goToTimezoneSettings = preventDoubleTap(() => {
|
||||
const {actions} = this.props;
|
||||
const {intl} = this.context;
|
||||
|
|
@ -104,11 +113,28 @@ export default class DisplaySettings extends PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
let sidebar;
|
||||
if (DeviceTypes.IS_TABLET) {
|
||||
sidebar = (
|
||||
<SettingsItem
|
||||
defaultMessage='Sidebar'
|
||||
i18nId='mobile.display_settings.sidebar'
|
||||
iconName='columns'
|
||||
iconType='fontawesome'
|
||||
onPress={this.goToSidebarSettings}
|
||||
separator={true}
|
||||
showArrow={false}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<StatusBar/>
|
||||
<View style={style.wrapper}>
|
||||
<View style={style.divider}/>
|
||||
{sidebar}
|
||||
{enableTheme && (
|
||||
<SettingsItem
|
||||
defaultMessage='Theme'
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@
|
|||
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
import SettingsItem from 'app/screens/settings/settings_item';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import {DeviceTypes} from 'app/constants';
|
||||
import SettingsItem from 'app/screens/settings/settings_item';
|
||||
|
||||
import DisplaySettings from './display_settings';
|
||||
|
||||
jest.mock('react-intl');
|
||||
|
|
@ -33,4 +36,19 @@ describe('DisplaySettings', () => {
|
|||
wrapper.setProps({enableTimezone: true});
|
||||
expect(wrapper.find(SettingsItem).length).toBe(3);
|
||||
});
|
||||
|
||||
test('should match snapshot on Tablet devices', () => {
|
||||
DeviceTypes.IS_TABLET = true;
|
||||
|
||||
const wrapper = shallow(
|
||||
<DisplaySettings {...baseProps}/>,
|
||||
);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
expect(wrapper.find(SettingsItem).length).toBe(2);
|
||||
wrapper.setProps({enableTheme: true});
|
||||
expect(wrapper.find(SettingsItem).length).toBe(3);
|
||||
wrapper.setProps({enableTimezone: true});
|
||||
expect(wrapper.find(SettingsItem).length).toBe(4);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
119
app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap
Normal file
119
app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SidebarSettings should match, full snapshot 1`] = `null`;
|
||||
|
||||
exports[`SidebarSettings should match, full snapshot 2`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Connect(StatusBar) />
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.06)",
|
||||
"flex": 1,
|
||||
"paddingTop": 35,
|
||||
}
|
||||
}
|
||||
>
|
||||
<section
|
||||
disableHeader={true}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.1)",
|
||||
"height": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<sectionItem
|
||||
action={[Function]}
|
||||
actionType="toggle"
|
||||
description={
|
||||
<FormattedText
|
||||
defaultMessage="Keep the sidebar open permanently"
|
||||
id="mobile.sidebar_settings.permanent_description"
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<FormattedText
|
||||
defaultMessage="Permanent Sidebar"
|
||||
id="mobile.sidebar_settings.permanent"
|
||||
/>
|
||||
}
|
||||
selected={false}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.1)",
|
||||
"height": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</section>
|
||||
</View>
|
||||
</View>
|
||||
`;
|
||||
119
app/screens/settings/sidebar/index.js
Normal file
119
app/screens/settings/sidebar/index.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
View,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import {intlShape} from 'react-intl';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
||||
import {DeviceTypes} from 'app/constants';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import Section from 'app/screens/settings/section';
|
||||
import SectionItem from 'app/screens/settings/section_item';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
export default class SidebarSettings extends PureComponent {
|
||||
static propTypes = {
|
||||
theme: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
intl: intlShape,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.loadSetting();
|
||||
}
|
||||
|
||||
loadSetting = async () => {
|
||||
const value = await AsyncStorage.getItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS);
|
||||
const enabled = Boolean(value === 'true');
|
||||
this.setState({enabled});
|
||||
};
|
||||
|
||||
saveSetting = (enabled) => {
|
||||
AsyncStorage.setItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, enabled.toString());
|
||||
this.setState({enabled}, () => EventEmitter.emit(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS));
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
theme,
|
||||
} = this.props;
|
||||
const {enabled} = this.state;
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
<View style={style.container}>
|
||||
<StatusBar/>
|
||||
<View style={style.wrapper}>
|
||||
<Section
|
||||
disableHeader={true}
|
||||
theme={theme}
|
||||
>
|
||||
<View style={style.divider}/>
|
||||
<SectionItem
|
||||
label={(
|
||||
<FormattedText
|
||||
id='mobile.sidebar_settings.permanent'
|
||||
defaultMessage='Permanent Sidebar'
|
||||
/>
|
||||
)}
|
||||
description={(
|
||||
<FormattedText
|
||||
id='mobile.sidebar_settings.permanent_description'
|
||||
defaultMessage='Keep the sidebar open permanently'
|
||||
/>
|
||||
)}
|
||||
action={this.saveSetting}
|
||||
actionType='toggle'
|
||||
selected={enabled}
|
||||
theme={theme}
|
||||
/>
|
||||
<View style={style.divider}/>
|
||||
</Section>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
wrapper: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.06),
|
||||
flex: 1,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingTop: 35,
|
||||
},
|
||||
}),
|
||||
},
|
||||
divider: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1),
|
||||
height: 1,
|
||||
},
|
||||
separator: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.1),
|
||||
height: 1,
|
||||
marginLeft: 15,
|
||||
},
|
||||
};
|
||||
});
|
||||
79
app/screens/settings/sidebar/sidebar.test.js
Normal file
79
app/screens/settings/sidebar/sidebar.test.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import {DeviceTypes} from 'app/constants';
|
||||
import MainSidebar from 'app/components/sidebars/main/main_sidebar';
|
||||
import SidebarSettings from './index';
|
||||
|
||||
jest.mock('react-intl');
|
||||
jest.mock('app/mattermost_managed', () => ({
|
||||
isRunningInSplitView: jest.fn().mockResolvedValue(false),
|
||||
}));
|
||||
|
||||
describe('SidebarSettings', () => {
|
||||
const baseProps = {
|
||||
theme: Preferences.THEMES.default,
|
||||
};
|
||||
|
||||
test('should match, full snapshot', async () => {
|
||||
const wrapper = shallow(
|
||||
<SidebarSettings {...baseProps}/>
|
||||
);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
|
||||
await wrapper.instance().loadSetting();
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should set the Permanent Sidebar value to false', async () => {
|
||||
const wrapper = shallow(
|
||||
<SidebarSettings {...baseProps}/>
|
||||
);
|
||||
|
||||
await wrapper.instance().loadSetting();
|
||||
expect(wrapper.state('enabled')).toBe(false);
|
||||
});
|
||||
|
||||
test('should set the Permanent Sidebar value to true and update the sidebar', async () => {
|
||||
DeviceTypes.IS_TABLET = true;
|
||||
|
||||
const wrapper = shallow(
|
||||
<SidebarSettings {...baseProps}/>
|
||||
);
|
||||
|
||||
const mainProps = {
|
||||
actions: {
|
||||
getTeams: jest.fn(),
|
||||
logChannelSwitch: jest.fn(),
|
||||
makeDirectChannel: jest.fn(),
|
||||
setChannelDisplayName: jest.fn(),
|
||||
setChannelLoading: jest.fn(),
|
||||
},
|
||||
blurPostTextBox: jest.fn(),
|
||||
currentTeamId: 'current-team-id',
|
||||
currentUserId: 'current-user-id',
|
||||
deviceWidth: 10,
|
||||
isLandscape: false,
|
||||
teamsCount: 2,
|
||||
theme: Preferences.THEMES.default,
|
||||
};
|
||||
|
||||
const mainSidebar = shallow(
|
||||
<MainSidebar {...mainProps}/>
|
||||
);
|
||||
|
||||
await wrapper.instance().loadSetting();
|
||||
expect(wrapper.state('enabled')).toBe(false);
|
||||
|
||||
await wrapper.instance().saveSetting(true);
|
||||
|
||||
expect(wrapper.state('enabled')).toBe(true);
|
||||
expect(mainSidebar.state('permanentSidebar')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
@ -207,6 +207,7 @@
|
|||
"mobile.create_channel.public": "New Public Channel",
|
||||
"mobile.create_post.read_only": "This channel is read-only",
|
||||
"mobile.custom_list.no_results": "No Results",
|
||||
"mobile.display_settings.sidebar": "Sidebar",
|
||||
"mobile.display_settings.theme": "Theme",
|
||||
"mobile.document_preview.failed_description": "An error occurred while opening the document. Please make sure you have a {fileType} viewer installed and try again.\n",
|
||||
"mobile.document_preview.failed_title": "Open Document failed",
|
||||
|
|
@ -435,11 +436,12 @@
|
|||
"mobile.share_extension.error_message": "An error has occurred while using the share extension.",
|
||||
"mobile.share_extension.error_title": "Extension Error",
|
||||
"mobile.share_extension.team": "Team",
|
||||
"mobile.sidebar_settings.permanent": "Permanent Sidebar",
|
||||
"mobile.sidebar_settings.permanent_description": "Keep the sidebar open permanently",
|
||||
"mobile.suggestion.members": "Members",
|
||||
"mobile.terms_of_service.alert_cancel": "Cancel",
|
||||
"mobile.terms_of_service.alert_ok": "OK",
|
||||
"mobile.terms_of_service.alert_retry": "Try Again",
|
||||
"mobile.terms_of_service.get_terms_error_description": "Make sure you have an internet connection or {refresh}. If this issue persists, contact your System Administrator.",
|
||||
"mobile.terms_of_service.terms_rejected": "You must agree to the terms of service before accessing {siteName}. Please contact your System Administrator for more details.",
|
||||
"mobile.timezone_settings.automatically": "Set automatically",
|
||||
"mobile.timezone_settings.manual": "Change timezone",
|
||||
|
|
|
|||
Loading…
Reference in a new issue