From c14714f16f1a4683b3b640845e6386ab4c6fbf5e Mon Sep 17 00:00:00 2001
From: pranavpandey1998official
<44601530+pranavpandey1998official@users.noreply.github.com>
Date: Tue, 11 Jun 2019 19:31:40 +0530
Subject: [PATCH] [NEW] Settings view (#900)
* new settings view
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* fix eslint
* eslint fixed all bugs and setup on my device
* move version from sidebar to settingsView
* add server Version not hard coded
* goto root stack after change language
* support RTL
* fix the ui of last section
* fixed bugs done requested changes
* added actions for contact us and license
* done requested changes
* removed verticle scroll indicator
* removed default export of device info
* fixed separator styling
* refactor Items in settings view
* changed language view
* change activeOpacity
* done requested changes
* fixed lint
* changed layout
* added test
* fix bug
* fix bug
* added e2e tests
* undone unnessary changes
* undone unnessary changes
* removed firebase
* Comment slash e2e tests
* Refactor Settings
* Refactor LanguageView
* Separator
* Unified styles
* fix indentation
---
__mocks__/reactotron-react-native.js | 3 +
app/containers/DisclosureIndicator.js | 5 +-
app/containers/ListItem.js | 93 ++++++
app/containers/Separator.js | 21 ++
app/i18n/locales/en.js | 11 +-
app/index.js | 4 +-
app/utils/deviceInfo.js | 9 +-
app/views/LanguageView/index.js | 158 +++++++++
app/views/SettingsView/index.js | 314 +++++++-----------
app/views/SettingsView/styles.js | 12 +
app/views/SidebarView/index.js | 4 -
app/views/Styles.js | 16 +-
e2e/08-room.spec.js | 46 +--
e2e/14-setting.spec.js | 94 ++++++
...room.spec.js => 15-joinpublicroom.spec.js} | 0
15 files changed, 556 insertions(+), 234 deletions(-)
create mode 100644 __mocks__/reactotron-react-native.js
create mode 100644 app/containers/ListItem.js
create mode 100644 app/containers/Separator.js
create mode 100644 app/views/LanguageView/index.js
create mode 100644 app/views/SettingsView/styles.js
create mode 100644 e2e/14-setting.spec.js
rename e2e/{14-joinpublicroom.spec.js => 15-joinpublicroom.spec.js} (100%)
diff --git a/__mocks__/reactotron-react-native.js b/__mocks__/reactotron-react-native.js
new file mode 100644
index 000000000..9180fdfe5
--- /dev/null
+++ b/__mocks__/reactotron-react-native.js
@@ -0,0 +1,3 @@
+export default {
+ createSagaMonitor: () => {}
+};
diff --git a/app/containers/DisclosureIndicator.js b/app/containers/DisclosureIndicator.js
index 03bed9861..25a284baf 100644
--- a/app/containers/DisclosureIndicator.js
+++ b/app/containers/DisclosureIndicator.js
@@ -14,9 +14,12 @@ const styles = StyleSheet.create({
}
});
+export const DisclosureImage = React.memo(() => );
+
const DisclosureIndicator = React.memo(() => (
-
+
));
+
export default DisclosureIndicator;
diff --git a/app/containers/ListItem.js b/app/containers/ListItem.js
new file mode 100644
index 000000000..069329343
--- /dev/null
+++ b/app/containers/ListItem.js
@@ -0,0 +1,93 @@
+import React from 'react';
+import { View, Text, StyleSheet } from 'react-native';
+import PropTypes from 'prop-types';
+import { RectButton } from 'react-native-gesture-handler';
+
+import { COLOR_TEXT } from '../constants/colors';
+import sharedStyles from '../views/Styles';
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ height: 56,
+ paddingHorizontal: 15
+ },
+ disabled: {
+ opacity: 0.3
+ },
+ textContainer: {
+ flex: 1,
+ justifyContent: 'center'
+ },
+ title: {
+ fontSize: 16,
+ ...sharedStyles.textColorNormal,
+ ...sharedStyles.textRegular
+ },
+ subtitle: {
+ fontSize: 14,
+ ...sharedStyles.textColorNormal,
+ ...sharedStyles.textRegular
+ }
+});
+
+const Content = React.memo(({
+ title, subtitle, disabled, testID, right
+}) => (
+
+
+ {title}
+ {subtitle
+ ? {subtitle}
+ : null
+ }
+
+ {right ? right() : null}
+
+));
+
+const Button = React.memo(({
+ onPress, ...props
+}) => (
+
+
+
+));
+
+const Item = React.memo(({ ...props }) => {
+ if (props.onPress) {
+ return ;
+ }
+ return ;
+});
+
+Item.propTypes = {
+ onPress: PropTypes.func
+};
+
+Content.propTypes = {
+ title: PropTypes.string.isRequired,
+ subtitle: PropTypes.string,
+ right: PropTypes.func,
+ disabled: PropTypes.bool,
+ testID: PropTypes.string
+};
+
+Button.propTypes = {
+ onPress: PropTypes.func,
+ disabled: PropTypes.bool
+};
+
+Button.defaultProps = {
+ disabled: false
+};
+
+export default Item;
diff --git a/app/containers/Separator.js b/app/containers/Separator.js
new file mode 100644
index 000000000..94ba3f7e7
--- /dev/null
+++ b/app/containers/Separator.js
@@ -0,0 +1,21 @@
+import React from 'react';
+import { View, StyleSheet } from 'react-native';
+import PropTypes from 'prop-types';
+
+import { COLOR_SEPARATOR } from '../constants/colors';
+
+const styles = StyleSheet.create({
+ separator: {
+ height: StyleSheet.hairlineWidth,
+ backgroundColor: COLOR_SEPARATOR
+ }
+});
+
+
+const Separator = React.memo(({ style }) => );
+
+Separator.propTypes = {
+ style: PropTypes.object
+};
+
+export default Separator;
diff --git a/app/i18n/locales/en.js b/app/i18n/locales/en.js
index b11c47cc5..08657afab 100644
--- a/app/i18n/locales/en.js
+++ b/app/i18n/locales/en.js
@@ -127,6 +127,7 @@ export default {
Connected: 'Connected',
connecting_server: 'connecting to server',
Connecting: 'Connecting...',
+ Contact_us: 'Contact us',
Continue_with: 'Continue with',
Copied_to_clipboard: 'Copied to clipboard!',
Copy: 'Copy',
@@ -190,6 +191,7 @@ export default {
leaving_room: 'leaving room',
leave: 'leave',
Legal: 'Legal',
+ License: 'License',
Livechat: 'Livechat',
Login: 'Login',
Login_error: 'Your credentials were rejected! Please try again.',
@@ -304,14 +306,17 @@ export default {
Select_Users: 'Select Users',
Send: 'Send',
Send_audio_message: 'Send audio message',
+ Send_crash_report: 'Send crash report',
Send_message: 'Send message',
Sent_an_attachment: 'Sent an attachment',
Server: 'Server',
Servers: 'Servers',
+ Server_version: 'Server version: {{version}}',
Set_username_subtitle: 'The username is used to allow others to mention you in messages',
Settings: 'Settings',
Settings_succesfully_changed: 'Settings succesfully changed!',
Share: 'Share',
+ Share_this_app: 'Share this app',
Sign_in_your_server: 'Sign in your server',
Sign_Up: 'Sign Up',
Some_field_is_invalid_or_empty: 'Some field is invalid or empty',
@@ -328,6 +333,7 @@ export default {
tap_to_change_status: 'tap to change status',
Tap_to_view_servers_list: 'Tap to view servers list',
Terms_of_Service: ' Terms of Service ',
+ Theme: 'Theme',
The_URL_is_invalid: 'The URL you entered is invalid. Check it and try again, please!',
There_was_an_error_while_action: 'There was an error while {{action}}!',
This_room_is_blocked: 'This room is blocked',
@@ -381,5 +387,8 @@ export default {
you_were_mentioned: 'you were mentioned',
you: 'you',
You: 'You',
- You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!'
+ Version_no: 'Version: {{version}}',
+ You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
+ Change_Language: 'Change Language',
+ Crash_report_disclaimer: 'We never track the content of your chats. The crash report only contains relevant information for us in order '
};
diff --git a/app/index.js b/app/index.js
index 65b001b29..04afb221a 100644
--- a/app/index.js
+++ b/app/index.js
@@ -23,6 +23,7 @@ import Navigation from './lib/Navigation';
import Sidebar from './views/SidebarView';
import ProfileView from './views/ProfileView';
import SettingsView from './views/SettingsView';
+import LanguageView from './views/LanguageView';
import AdminPanelView from './views/AdminPanelView';
import RoomActionsView from './views/RoomActionsView';
import RoomInfoView from './views/RoomInfoView';
@@ -148,7 +149,8 @@ ProfileStack.navigationOptions = ({ navigation }) => {
};
const SettingsStack = createStackNavigator({
- SettingsView
+ SettingsView,
+ LanguageView
}, {
defaultNavigationOptions: defaultHeader
});
diff --git a/app/utils/deviceInfo.js b/app/utils/deviceInfo.js
index 2ee460af5..cc2b493b7 100644
--- a/app/utils/deviceInfo.js
+++ b/app/utils/deviceInfo.js
@@ -8,11 +8,4 @@ export const isIOS = Platform.OS === 'ios';
export const isAndroid = !isIOS;
export const getReadableVersion = DeviceInfo.getReadableVersion();
export const getBundleId = DeviceInfo.getBundleId();
-
-export default {
- isNotch,
- isIOS,
- isAndroid,
- getReadableVersion,
- getBundleId
-};
+export const getDeviceModel = DeviceInfo.getModel();
diff --git a/app/views/LanguageView/index.js b/app/views/LanguageView/index.js
new file mode 100644
index 000000000..045d2e9c5
--- /dev/null
+++ b/app/views/LanguageView/index.js
@@ -0,0 +1,158 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { FlatList } from 'react-native';
+import { connect } from 'react-redux';
+import { SafeAreaView, NavigationActions } from 'react-navigation';
+
+import RocketChat from '../../lib/rocketchat';
+import I18n from '../../i18n';
+import Loading from '../../containers/Loading';
+import { showErrorAlert } from '../../utils/info';
+import log from '../../utils/log';
+import { setUser as setUserAction } from '../../actions/login';
+import StatusBar from '../../containers/StatusBar';
+import { CustomIcon } from '../../lib/Icons';
+import sharedStyles from '../Styles';
+import ListItem from '../../containers/ListItem';
+import Separator from '../../containers/Separator';
+
+const LANGUAGES = [
+ {
+ label: '简体中文',
+ value: 'zh-CN'
+ }, {
+ label: 'Deutsch',
+ value: 'de'
+ }, {
+ label: 'English',
+ value: 'en'
+ }, {
+ label: 'Français',
+ value: 'fr'
+ }, {
+ label: 'Português (BR)',
+ value: 'pt-BR'
+ }, {
+ label: 'Português (PT)',
+ value: 'pt-PT'
+ }, {
+ label: 'Russian',
+ value: 'ru'
+ }
+];
+
+@connect(state => ({
+ userLanguage: state.login.user && state.login.user.language
+}), dispatch => ({
+ setUser: params => dispatch(setUserAction(params))
+}))
+/** @extends React.Component */
+export default class LanguageView extends React.Component {
+ static navigationOptions = () => ({
+ title: I18n.t('Change_Language')
+ })
+
+ static propTypes = {
+ userLanguage: PropTypes.string,
+ navigation: PropTypes.object,
+ setUser: PropTypes.func
+ }
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ language: props.userLanguage ? props.userLanguage : 'en',
+ saving: false
+ };
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ const { language, saving } = this.state;
+ const { userLanguage } = this.props;
+ if (nextState.language !== language) {
+ return true;
+ }
+ if (nextState.saving !== saving) {
+ return true;
+ }
+ if (nextProps.userLanguage !== userLanguage) {
+ return true;
+ }
+ return false;
+ }
+
+ formIsChanged = (language) => {
+ const { userLanguage } = this.props;
+ return (userLanguage !== language);
+ }
+
+ submit = async(language) => {
+ if (!this.formIsChanged(language)) {
+ return;
+ }
+
+ this.setState({ saving: true });
+
+ const { userLanguage, setUser, navigation } = this.props;
+
+ const params = {};
+
+ // language
+ if (userLanguage !== language) {
+ params.language = language;
+ }
+
+ try {
+ await RocketChat.saveUserPreferences(params);
+ setUser({ language: params.language });
+
+ this.setState({ saving: false });
+ setTimeout(() => {
+ navigation.reset([NavigationActions.navigate({ routeName: 'SettingsView' })], 0);
+ navigation.navigate('RoomsListView');
+ }, 300);
+ } catch (e) {
+ this.setState({ saving: false });
+ setTimeout(() => {
+ showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') }));
+ log('err_save_user_preferences', e);
+ }, 300);
+ }
+ }
+
+ renderSeparator = () =>
+
+ renderIcon = () =>
+
+ renderItem = ({ item }) => {
+ const { value, label } = item;
+ const { language } = this.state;
+ const isSelected = language === value;
+
+ return (
+ this.submit(value)}
+ testID={`language-view-${ value }`}
+ right={isSelected ? this.renderIcon : null}
+ />
+ );
+ }
+
+ render() {
+ const { saving } = this.state;
+ return (
+
+
+ item.value}
+ contentContainerStyle={sharedStyles.listContentContainer}
+ renderItem={this.renderItem}
+ ItemSeparatorComponent={this.renderSeparator}
+ />
+
+
+ );
+ }
+}
diff --git a/app/views/SettingsView/index.js b/app/views/SettingsView/index.js
index 39e4dd5e9..b66f7cc84 100644
--- a/app/views/SettingsView/index.js
+++ b/app/views/SettingsView/index.js
@@ -1,236 +1,160 @@
import React from 'react';
-import PropTypes from 'prop-types';
import {
- View, ScrollView, Switch, Text, StyleSheet, AsyncStorage
+ View, Linking, ScrollView, AsyncStorage, SafeAreaView, Switch
} from 'react-native';
-import RNPickerSelect from 'react-native-picker-select';
+import PropTypes from 'prop-types';
import { connect } from 'react-redux';
-import { SafeAreaView } from 'react-navigation';
-import firebase from 'react-native-firebase';
-import RocketChat, { MARKDOWN_KEY } from '../../lib/rocketchat';
-import KeyboardView from '../../presentation/KeyboardView';
-import sharedStyles from '../Styles';
-import RCTextInput from '../../containers/TextInput';
-import scrollPersistTaps from '../../utils/scrollPersistTaps';
-import I18n from '../../i18n';
-import Button from '../../containers/Button';
-import Loading from '../../containers/Loading';
-import { showErrorAlert, Toast } from '../../utils/info';
-import log from '../../utils/log';
-import { setUser as setUserAction } from '../../actions/login';
import { toggleMarkdown as toggleMarkdownAction } from '../../actions/markdown';
+import { COLOR_DANGER, COLOR_SUCCESS } from '../../constants/colors';
import { DrawerButton } from '../../containers/HeaderButton';
import StatusBar from '../../containers/StatusBar';
-import { isAndroid } from '../../utils/deviceInfo';
-import {
- COLOR_WHITE, COLOR_SEPARATOR, COLOR_DANGER, COLOR_SUCCESS
-} from '../../constants/colors';
+import ListItem from '../../containers/ListItem';
+import { DisclosureImage } from '../../containers/DisclosureIndicator';
+import Separator from '../../containers/Separator';
+import I18n from '../../i18n';
+import { MARKDOWN_KEY } from '../../lib/rocketchat';
+import { getReadableVersion, getDeviceModel, isAndroid } from '../../utils/deviceInfo';
+import openLink from '../../utils/openLink';
+import scrollPersistTaps from '../../utils/scrollPersistTaps';
+import { showErrorAlert } from '../../utils/info';
+import styles from './styles';
+import sharedStyles from '../Styles';
-const styles = StyleSheet.create({
- swithContainer: {
- backgroundColor: COLOR_WHITE,
- alignItems: 'center',
- justifyContent: 'space-between',
- flexDirection: 'row'
- },
- label: {
- fontSize: 17,
- flex: 1,
- ...sharedStyles.textMedium,
- ...sharedStyles.textColorNormal
- },
- separator: {
- flex: 1,
- height: 1,
- backgroundColor: COLOR_SEPARATOR,
- marginVertical: 10
- }
-});
+const LICENSE_LINK = 'https://github.com/RocketChat/Rocket.Chat.ReactNative/blob/develop/LICENSE';
+const SectionSeparator = React.memo(() => );
+const SWITCH_TRACK_COLOR = {
+ false: isAndroid ? COLOR_DANGER : null,
+ true: COLOR_SUCCESS
+};
@connect(state => ({
- userLanguage: state.login.user && state.login.user.language,
+ server: state.server,
useMarkdown: state.markdown.useMarkdown
}), dispatch => ({
- setUser: params => dispatch(setUserAction(params)),
toggleMarkdown: params => dispatch(toggleMarkdownAction(params))
}))
export default class SettingsView extends React.Component {
static navigationOptions = ({ navigation }) => ({
headerLeft: ,
title: I18n.t('Settings')
- })
+ });
static propTypes = {
- componentId: PropTypes.string,
- userLanguage: PropTypes.string,
+ navigation: PropTypes.object,
+ server: PropTypes.object,
useMarkdown: PropTypes.bool,
- setUser: PropTypes.func,
toggleMarkdown: PropTypes.func
}
- constructor(props) {
- super(props);
- this.state = {
- placeholder: {},
- language: props.userLanguage ? props.userLanguage : 'en',
- languages: [{
- label: 'English',
- value: 'en'
- }, {
- label: 'Português (BR)',
- value: 'pt-BR'
- }, {
- label: 'Russian',
- value: 'ru'
- }, {
- label: '简体中文',
- value: 'zh-CN'
- }, {
- label: 'Français',
- value: 'fr'
- }, {
- label: 'Deutsch',
- value: 'de'
- }, {
- label: 'Português (PT)',
- value: 'pt-PT'
- }],
- saving: false
- };
- }
-
- shouldComponentUpdate(nextProps, nextState) {
- const { language, saving } = this.state;
- const { userLanguage, useMarkdown } = this.props;
- if (nextState.language !== language) {
- return true;
- }
- if (nextState.saving !== saving) {
- return true;
- }
- if (nextProps.useMarkdown !== useMarkdown) {
- return true;
- }
- if (nextProps.userLanguage !== userLanguage) {
- return true;
- }
- return false;
- }
-
- getLabel = (language) => {
- const { languages } = this.state;
- const l = languages.find(i => i.value === language);
- if (l && l.label) {
- return l.label;
- }
- return null;
- }
-
- formIsChanged = () => {
- const { userLanguage } = this.props;
- const { language } = this.state;
- return !(userLanguage === language);
- }
-
- submit = async() => {
- this.setState({ saving: true });
-
- const { language } = this.state;
- const { userLanguage, setUser } = this.props;
-
- if (!this.formIsChanged()) {
- return;
- }
-
- const params = {};
-
- // language
- if (userLanguage !== language) {
- params.language = language;
- }
-
- try {
- await RocketChat.saveUserPreferences(params);
- setUser({ language: params.language });
-
- this.setState({ saving: false });
- setTimeout(() => {
- this.toast.show(I18n.t('Preferences_saved'));
- }, 300);
- } catch (e) {
- this.setState({ saving: false });
- setTimeout(() => {
- showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') }));
- log('err_save_user_preferences', e);
- }, 300);
- }
- }
-
toggleMarkdown = (value) => {
AsyncStorage.setItem(MARKDOWN_KEY, JSON.stringify(value));
const { toggleMarkdown } = this.props;
toggleMarkdown(value);
- firebase.analytics().logEvent('toggle_markdown', { value });
+ }
+
+ navigateToRoom = (room) => {
+ const { navigation } = this.props;
+ navigation.navigate(room);
+ }
+
+ sendEmail = async() => {
+ const subject = encodeURI('React Native App Support');
+ const email = encodeURI('support@rocket.chat');
+ const description = encodeURI(`
+ version: ${ getReadableVersion }
+ device: ${ getDeviceModel }
+ `);
+ try {
+ await Linking.openURL(`mailto:${ email }?subject=${ subject }&body=${ description }`);
+ } catch (e) {
+ showErrorAlert(I18n.t('error-email-send-failed', { message: 'support@rocket.chat' }));
+ }
+ }
+
+ onPressLicense = () => openLink(LICENSE_LINK)
+
+ renderDisclosure = () =>
+
+ renderMarkdownSwitch = () => {
+ const { useMarkdown } = this.props;
+ return (
+
+ );
}
render() {
- const {
- language, languages, placeholder, saving
- } = this.state;
- const { useMarkdown } = this.props;
+ const { server } = this.props;
return (
-
+
-
- {
- this.setState({ language: value });
- }}
- value={language}
- placeholder={placeholder}
- >
- { this.name = e; }}
- label={I18n.t('Language')}
- placeholder={I18n.t('Language')}
- value={this.getLabel(language)}
- testID='settings-view-language'
- />
-
-
-
-
-
-
- {I18n.t('Enable_markdown')}
-
-
-
- this.toast = toast} />
-
+
+
+ this.navigateToRoom('LanguageView')}
+ showActionIndicator
+ testID='settings-view-language'
+ right={this.renderDisclosure}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ this.renderMarkdownSwitch()}
+ />
-
+
);
}
}
diff --git a/app/views/SettingsView/styles.js b/app/views/SettingsView/styles.js
new file mode 100644
index 000000000..74f57651c
--- /dev/null
+++ b/app/views/SettingsView/styles.js
@@ -0,0 +1,12 @@
+import { StyleSheet } from 'react-native';
+
+import { COLOR_BACKGROUND_CONTAINER } from '../../constants/colors';
+import sharedStyles from '../Styles';
+
+export default StyleSheet.create({
+ sectionSeparatorBorder: {
+ ...sharedStyles.separatorVertical,
+ backgroundColor: COLOR_BACKGROUND_CONTAINER,
+ height: 10
+ }
+});
diff --git a/app/views/SidebarView/index.js b/app/views/SidebarView/index.js
index c2de3dd84..49a0fa9e7 100644
--- a/app/views/SidebarView/index.js
+++ b/app/views/SidebarView/index.js
@@ -15,7 +15,6 @@ import RocketChat from '../../lib/rocketchat';
import log from '../../utils/log';
import I18n from '../../i18n';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
-import { getReadableVersion } from '../../utils/deviceInfo';
import { CustomIcon } from '../../lib/Icons';
import styles from './styles';
import SidebarItem from './SidebarItem';
@@ -279,9 +278,6 @@ export default class Sidebar extends Component {
{!showStatus ? this.renderNavigation() : null}
{showStatus ? this.renderStatus() : null}
-
- {getReadableVersion}
-
);
}
diff --git a/app/views/Styles.js b/app/views/Styles.js
index eaff9eef7..8f8040cca 100644
--- a/app/views/Styles.js
+++ b/app/views/Styles.js
@@ -1,7 +1,7 @@
import { StyleSheet, Platform } from 'react-native';
import {
- COLOR_DANGER, COLOR_BUTTON_PRIMARY, COLOR_SEPARATOR, COLOR_TEXT, COLOR_TEXT_DESCRIPTION, COLOR_TITLE
+ COLOR_DANGER, COLOR_BUTTON_PRIMARY, COLOR_SEPARATOR, COLOR_TEXT, COLOR_TEXT_DESCRIPTION, COLOR_TITLE, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE, COLOR_PRIMARY
} from '../constants/colors';
export default StyleSheet.create({
@@ -176,7 +176,21 @@ export default StyleSheet.create({
textColorDescription: {
color: COLOR_TEXT_DESCRIPTION
},
+ colorPrimary: {
+ color: COLOR_PRIMARY
+ },
inputLastChild: {
marginBottom: 15
+ },
+ listSafeArea: {
+ flex: 1,
+ backgroundColor: COLOR_BACKGROUND_CONTAINER
+ },
+ listContentContainer: {
+ borderColor: COLOR_SEPARATOR,
+ borderTopWidth: StyleSheet.hairlineWidth,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ backgroundColor: COLOR_WHITE,
+ marginVertical: 10
}
});
diff --git a/e2e/08-room.spec.js b/e2e/08-room.spec.js
index 9a00ca464..054784053 100644
--- a/e2e/08-room.spec.js
+++ b/e2e/08-room.spec.js
@@ -159,30 +159,30 @@ describe('Room screen', () => {
await element(by.id('messagebox-input')).clearText();
});
- it('should show and tap on slash command autocomplete and send slash command', async() => {
- await element(by.id('messagebox-input')).tap();
- await element(by.id('messagebox-input')).typeText('/');
- await waitFor(element(by.id('messagebox-container'))).toBeVisible().withTimeout(10000);
- await expect(element(by.id('messagebox-container'))).toBeVisible();
- await element(by.id('mention-item-shrug')).tap();
- await expect(element(by.id('messagebox-input'))).toHaveText('/shrug ');
- await element(by.id('messagebox-input')).typeText('joy'); // workaround for number keyboard
- await element(by.id('messagebox-send-message')).tap();
- await waitFor(element(by.text(`joy ¯\_(ツ)_/¯`))).toBeVisible().withTimeout(60000);
- });
+ // it('should show and tap on slash command autocomplete and send slash command', async() => {
+ // await element(by.id('messagebox-input')).tap();
+ // await element(by.id('messagebox-input')).typeText('/');
+ // await waitFor(element(by.id('messagebox-container'))).toBeVisible().withTimeout(10000);
+ // await expect(element(by.id('messagebox-container'))).toBeVisible();
+ // await element(by.id('mention-item-shrug')).tap();
+ // await expect(element(by.id('messagebox-input'))).toHaveText('/shrug ');
+ // await element(by.id('messagebox-input')).typeText('joy'); // workaround for number keyboard
+ // await element(by.id('messagebox-send-message')).tap();
+ // await waitFor(element(by.text(`joy ¯\_(ツ)_/¯`))).toBeVisible().withTimeout(60000);
+ // });
- it('should show command Preview', async() => {
- await element(by.id('messagebox-input')).tap();
- await element(by.id('messagebox-input')).replaceText('/giphy');
- await waitFor(element(by.id('messagebox-container'))).toBeVisible().withTimeout(10000);
- await expect(element(by.id('messagebox-container'))).toBeVisible();
- await element(by.id('mention-item-giphy')).tap();
- await expect(element(by.id('messagebox-input'))).toHaveText('/giphy ');
- await element(by.id('messagebox-input')).typeText('no'); // workaround for number keyboard
- await waitFor(element(by.id('commandbox-container'))).toBeVisible().withTimeout(10000);
- await expect(element(by.id('commandbox-container'))).toBeVisible();
- await element(by.id('messagebox-input')).clearText();
- });
+ // it('should show command Preview', async() => {
+ // await element(by.id('messagebox-input')).tap();
+ // await element(by.id('messagebox-input')).replaceText('/giphy');
+ // await waitFor(element(by.id('messagebox-container'))).toBeVisible().withTimeout(10000);
+ // await expect(element(by.id('messagebox-container'))).toBeVisible();
+ // await element(by.id('mention-item-giphy')).tap();
+ // await expect(element(by.id('messagebox-input'))).toHaveText('/giphy ');
+ // await element(by.id('messagebox-input')).typeText('no'); // workaround for number keyboard
+ // await waitFor(element(by.id('commandbox-container'))).toBeVisible().withTimeout(10000);
+ // await expect(element(by.id('commandbox-container'))).toBeVisible();
+ // await element(by.id('messagebox-input')).clearText();
+ // });
});
describe('Message', async() => {
diff --git a/e2e/14-setting.spec.js b/e2e/14-setting.spec.js
new file mode 100644
index 000000000..326c5dd7b
--- /dev/null
+++ b/e2e/14-setting.spec.js
@@ -0,0 +1,94 @@
+const {
+ device, expect, element, by, waitFor
+} = require('detox');
+const { takeScreenshot } = require('./helpers/screenshot');
+const { logout, navigateToLogin, login } = require('./helpers/app');
+
+describe('Settings screen', () => {
+ before(async() => {
+ await device.reloadReactNative();
+ await expect(element(by.id('rooms-list-view'))).toBeVisible();
+ await element(by.id('rooms-list-view-sidebar')).tap();
+ await waitFor(element(by.id('sidebar-view'))).toBeVisible().withTimeout(2000);
+ await waitFor(element(by.id('sidebar-settings'))).toBeVisible().withTimeout(2000);
+ await element(by.id('sidebar-settings')).tap();
+ await waitFor(element(by.id('settings-view'))).toBeVisible().withTimeout(2000);
+
+ });
+
+ describe('Render', async() => {
+ it('should have settings view', async() => {
+ await expect(element(by.id('settings-view'))).toBeVisible();
+ });
+
+ it('should have language', async() => {
+ await expect(element(by.id('settings-view-language'))).toExist();
+ });
+
+ it('should have theme', async() => {
+ await expect(element(by.id('settings-view-theme'))).toExist();
+ });
+
+ it('should have share app', async() => {
+ await expect(element(by.id('settings-view-share-app'))).toExist();
+ });
+
+ it('should have licence', async() => {
+ await expect(element(by.id('settings-view-license'))).toExist();
+ });
+
+ it('should have version no', async() => {
+ await expect(element(by.id('settings-view-version'))).toExist();
+ });
+
+ it('should have server version', async() => {
+ await expect(element(by.id('settings-view-server-version'))).toExist();
+ });
+
+ it('should have enable markdown', async() => {
+ await expect(element(by.id('settings-view-markdown'))).toExist();
+ });
+
+ after(async() => {
+ takeScreenshot();
+ });
+ });
+
+ describe('Language', async() => {
+ it('should navigate to language view', async() => {
+ await element(by.id('settings-view-language')).tap();
+ await waitFor(element(by.id('language-view'))).toBeVisible().withTimeout(60000);
+ await expect(element(by.id('language-view-zh-CN'))).toExist();
+ await expect(element(by.id('language-view-de'))).toExist();
+ await expect(element(by.id('language-view-en'))).toExist();
+ await expect(element(by.id('language-view-fr'))).toExist();
+ await expect(element(by.id('language-view-pt-BR'))).toExist();
+ await expect(element(by.id('language-view-pt-PT'))).toExist();
+ await expect(element(by.id('language-view-ru'))).toExist();
+ });
+
+ it('should navigate to change language', async() => {
+ await expect(element(by.id('language-view-zh-CN'))).toExist();
+ await element(by.id('language-view-zh-CN')).tap()
+ await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(60000);
+ await expect(element(by.id('rooms-list-view'))).toBeVisible();
+ await element(by.id('rooms-list-view-sidebar')).tap();
+ await waitFor(element(by.id('sidebar-view'))).toBeVisible().withTimeout(2000);
+ await waitFor(element(by.text('设置'))).toBeVisible().withTimeout(2000);
+ await element(by.text('设置')).tap();
+ await waitFor(element(by.id('settings-view'))).toBeVisible().withTimeout(2000);
+ await element(by.id('settings-view-language')).tap();
+ await element(by.id('language-view-en')).tap();
+ await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(60000);
+ await expect(element(by.id('rooms-list-view'))).toBeVisible();
+ await element(by.id('rooms-list-view-sidebar')).tap();
+ await waitFor(element(by.id('sidebar-view'))).toBeVisible().withTimeout(2000);
+ await expect(element(by.text('Settings'))).toBeVisible();
+ await element(by.text('Settings')).tap();
+ await expect(element(by.id('settings-view'))).toBeVisible();
+ });
+ after(async() => {
+ takeScreenshot();
+ });
+ });
+});
diff --git a/e2e/14-joinpublicroom.spec.js b/e2e/15-joinpublicroom.spec.js
similarity index 100%
rename from e2e/14-joinpublicroom.spec.js
rename to e2e/15-joinpublicroom.spec.js