Compare commits
22 Commits
develop
...
new.create
Author | SHA1 | Date |
---|---|---|
Diego Mello | db30859a22 | |
Diego Mello | 0963706266 | |
Diego Mello | b7e075df02 | |
Diego Mello | 943e179e18 | |
Reinaldo Neto | 64f4cc3cf1 | |
Reinaldo Neto | a33eeee317 | |
Reinaldo Neto | f7ef6c61cf | |
Diego Mello | 996b3242ea | |
Diego Mello | e01c31dbf3 | |
Reinaldo Neto | 72b6034d7f | |
Reinaldo Neto | cd583bb503 | |
Diego Mello | 38b8415c73 | |
Reinaldo Neto | d6f9d1d64a | |
Reinaldo Neto | fa87dc6c58 | |
Reinaldo Neto | 9ed35f0f1d | |
Reinaldo Neto | 8d5137ca5b | |
Reinaldo Neto | 9449949ac3 | |
Reinaldo Neto | c57caafaf8 | |
Reinaldo Neto | 06ca560e43 | |
Reinaldo Neto | 5e3eddc66f | |
Reinaldo Neto | 1a63e80861 | |
Reinaldo Neto | 6008b9cacb |
|
@ -5,7 +5,7 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import Navigation from './lib/Navigation';
|
import Navigation from './lib/Navigation';
|
||||||
import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation';
|
import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation';
|
||||||
import { ROOT_INSIDE, ROOT_LOADING, ROOT_NEW_SERVER, ROOT_OUTSIDE, ROOT_SET_USERNAME } from './actions/app';
|
import { ROOT_INSIDE, ROOT_LOADING, ROOT_OUTSIDE, ROOT_SET_USERNAME } from './actions/app';
|
||||||
// Stacks
|
// Stacks
|
||||||
import AuthLoadingView from './views/AuthLoadingView';
|
import AuthLoadingView from './views/AuthLoadingView';
|
||||||
// SetUsername Stack
|
// SetUsername Stack
|
||||||
|
@ -56,9 +56,7 @@ const App = React.memo(({ root, isMasterDetail }: { root: string; isMasterDetail
|
||||||
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
|
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
|
||||||
<>
|
<>
|
||||||
{root === ROOT_LOADING ? <Stack.Screen name='AuthLoading' component={AuthLoadingView} /> : null}
|
{root === ROOT_LOADING ? <Stack.Screen name='AuthLoading' component={AuthLoadingView} /> : null}
|
||||||
{root === ROOT_OUTSIDE || root === ROOT_NEW_SERVER ? (
|
{root === ROOT_OUTSIDE ? <Stack.Screen name='OutsideStack' component={OutsideStack} /> : null}
|
||||||
<Stack.Screen name='OutsideStack' component={OutsideStack} />
|
|
||||||
) : null}
|
|
||||||
{root === ROOT_INSIDE && isMasterDetail ? (
|
{root === ROOT_INSIDE && isMasterDetail ? (
|
||||||
<Stack.Screen name='MasterDetailStack' component={MasterDetailStack} />
|
<Stack.Screen name='MasterDetailStack' component={MasterDetailStack} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { APP } from './actionsTypes';
|
||||||
export const ROOT_OUTSIDE = 'outside';
|
export const ROOT_OUTSIDE = 'outside';
|
||||||
export const ROOT_INSIDE = 'inside';
|
export const ROOT_INSIDE = 'inside';
|
||||||
export const ROOT_LOADING = 'loading';
|
export const ROOT_LOADING = 'loading';
|
||||||
export const ROOT_NEW_SERVER = 'newServer';
|
|
||||||
export const ROOT_SET_USERNAME = 'setUsername';
|
export const ROOT_SET_USERNAME = 'setUsername';
|
||||||
|
|
||||||
export function appStart({ root, ...args }) {
|
export function appStart({ root, ...args }) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ interface IButtonProps {
|
||||||
color: string;
|
color: string;
|
||||||
fontSize: any;
|
fontSize: any;
|
||||||
style: any;
|
style: any;
|
||||||
|
styleText?: any;
|
||||||
testID: string;
|
testID: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +49,8 @@ export default class Button extends React.PureComponent<Partial<IButtonProps>, a
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { title, type, onPress, disabled, backgroundColor, color, loading, style, theme, fontSize, ...otherProps } = this.props;
|
const { title, type, onPress, disabled, backgroundColor, color, loading, style, theme, fontSize, styleText, ...otherProps } =
|
||||||
|
this.props;
|
||||||
const isPrimary = type === 'primary';
|
const isPrimary = type === 'primary';
|
||||||
|
|
||||||
let textColor = isPrimary ? themes[theme!].buttonText : themes[theme!].bodyText;
|
let textColor = isPrimary ? themes[theme!].buttonText : themes[theme!].bodyText;
|
||||||
|
@ -72,7 +74,7 @@ export default class Button extends React.PureComponent<Partial<IButtonProps>, a
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<ActivityIndicator color={textColor} />
|
<ActivityIndicator color={textColor} />
|
||||||
) : (
|
) : (
|
||||||
<Text style={[styles.text, { color: textColor }, fontSize && { fontSize }]} accessibilityLabel={title}>
|
<Text style={[styles.text, { color: textColor }, fontSize && { fontSize }, styleText]} accessibilityLabel={title}>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -7,7 +7,6 @@ const initialState = {
|
||||||
server: '',
|
server: '',
|
||||||
version: null,
|
version: null,
|
||||||
loading: true,
|
loading: true,
|
||||||
adding: false,
|
|
||||||
previousServer: null,
|
previousServer: null,
|
||||||
changingServer: false
|
changingServer: false
|
||||||
};
|
};
|
||||||
|
@ -58,13 +57,11 @@ export default function server(state = initialState, action) {
|
||||||
case SERVER.INIT_ADD:
|
case SERVER.INIT_ADD:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
adding: true,
|
|
||||||
previousServer: action.previousServer
|
previousServer: action.previousServer
|
||||||
};
|
};
|
||||||
case SERVER.FINISH_ADD:
|
case SERVER.FINISH_ADD:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
adding: false,
|
|
||||||
previousServer: null
|
previousServer: null
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { inviteLinksRequest, inviteLinksSetToken } from '../actions/inviteLinks'
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import EventEmitter from '../utils/events';
|
import EventEmitter from '../utils/events';
|
||||||
import { ROOT_INSIDE, ROOT_NEW_SERVER, appInit, appStart } from '../actions/app';
|
import { ROOT_INSIDE, ROOT_OUTSIDE, appInit, appStart } from '../actions/app';
|
||||||
import { localAuthenticate } from '../utils/localAuthentication';
|
import { localAuthenticate } from '../utils/localAuthentication';
|
||||||
import { goRoom } from '../utils/goRoom';
|
import { goRoom } from '../utils/goRoom';
|
||||||
import { loginRequest } from '../actions/login';
|
import { loginRequest } from '../actions/login';
|
||||||
|
@ -180,7 +180,7 @@ const handleOpen = function* handleOpen({ params }) {
|
||||||
yield fallbackNavigation();
|
yield fallbackNavigation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
yield put(appStart({ root: ROOT_NEW_SERVER }));
|
yield put(appStart({ root: ROOT_OUTSIDE }));
|
||||||
yield put(serverInitAdd(server));
|
yield put(serverInitAdd(server));
|
||||||
yield delay(1000);
|
yield delay(1000);
|
||||||
EventEmitter.emit('NewServer', { server: host });
|
EventEmitter.emit('NewServer', { server: host });
|
||||||
|
|
|
@ -118,8 +118,6 @@ const fetchRooms = function* fetchRooms() {
|
||||||
|
|
||||||
const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
try {
|
try {
|
||||||
const adding = yield select(state => state.server.adding);
|
|
||||||
|
|
||||||
RocketChat.getUserPresence(user.id);
|
RocketChat.getUserPresence(user.id);
|
||||||
|
|
||||||
const server = yield select(getServer);
|
const server = yield select(getServer);
|
||||||
|
@ -170,25 +168,11 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
yield put(setUser(user));
|
yield put(setUser(user));
|
||||||
EventEmitter.emit('connected');
|
EventEmitter.emit('connected');
|
||||||
|
|
||||||
let currentRoot;
|
|
||||||
if (adding) {
|
|
||||||
yield put(serverFinishAdd());
|
|
||||||
yield put(appStart({ root: ROOT_INSIDE }));
|
yield put(appStart({ root: ROOT_INSIDE }));
|
||||||
} else {
|
|
||||||
currentRoot = yield select(state => state.app.root);
|
|
||||||
if (currentRoot !== ROOT_INSIDE) {
|
|
||||||
yield put(appStart({ root: ROOT_INSIDE }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// after a successful login, check if it's been invited via invite link
|
|
||||||
currentRoot = yield select(state => state.app.root);
|
|
||||||
if (currentRoot === ROOT_INSIDE) {
|
|
||||||
const inviteLinkToken = yield select(state => state.inviteLinks.token);
|
const inviteLinkToken = yield select(state => state.inviteLinks.token);
|
||||||
if (inviteLinkToken) {
|
if (inviteLinkToken) {
|
||||||
yield put(inviteLinksRequest(inviteLinkToken));
|
yield put(inviteLinksRequest(inviteLinkToken));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { put, takeLatest } from 'redux-saga/effects';
|
import { put, takeLatest, select } from 'redux-saga/effects';
|
||||||
import { Alert } from 'react-native';
|
import { Alert } from 'react-native';
|
||||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
@ -7,7 +7,7 @@ import coerce from 'semver/functions/coerce';
|
||||||
|
|
||||||
import Navigation from '../lib/Navigation';
|
import Navigation from '../lib/Navigation';
|
||||||
import { SERVER } from '../actions/actionsTypes';
|
import { SERVER } from '../actions/actionsTypes';
|
||||||
import { selectServerFailure, selectServerRequest, selectServerSuccess, serverFailure } from '../actions/server';
|
import { selectServerFailure, selectServerRequest, selectServerSuccess, serverFailure, serverFinishAdd } from '../actions/server';
|
||||||
import { clearSettings } from '../actions/settings';
|
import { clearSettings } from '../actions/settings';
|
||||||
import { setUser } from '../actions/login';
|
import { setUser } from '../actions/login';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { createStackNavigator } from '@react-navigation/stack';
|
import { createStackNavigator } from '@react-navigation/stack';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import { ThemeContext } from '../theme';
|
import { ThemeContext } from '../theme';
|
||||||
import { ModalAnimation, StackAnimation, defaultHeader, themedHeader } from '../utils/navigation';
|
import { ModalAnimation, StackAnimation, defaultHeader, themedHeader } from '../utils/navigation';
|
||||||
|
|
||||||
// Outside Stack
|
// Outside Stack
|
||||||
import OnboardingView from '../views/OnboardingView';
|
|
||||||
import NewServerView from '../views/NewServerView';
|
import NewServerView from '../views/NewServerView';
|
||||||
import WorkspaceView from '../views/WorkspaceView';
|
import WorkspaceView from '../views/WorkspaceView';
|
||||||
import LoginView from '../views/LoginView';
|
import LoginView from '../views/LoginView';
|
||||||
|
@ -15,18 +13,14 @@ import ForgotPasswordView from '../views/ForgotPasswordView';
|
||||||
import RegisterView from '../views/RegisterView';
|
import RegisterView from '../views/RegisterView';
|
||||||
import LegalView from '../views/LegalView';
|
import LegalView from '../views/LegalView';
|
||||||
import AuthenticationWebView from '../views/AuthenticationWebView';
|
import AuthenticationWebView from '../views/AuthenticationWebView';
|
||||||
import { ROOT_OUTSIDE } from '../actions/app';
|
|
||||||
|
|
||||||
// Outside
|
// Outside
|
||||||
const Outside = createStackNavigator();
|
const Outside = createStackNavigator();
|
||||||
const _OutsideStack = ({ root }) => {
|
const _OutsideStack = () => {
|
||||||
const { theme } = React.useContext(ThemeContext);
|
const { theme } = React.useContext(ThemeContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Outside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation }}>
|
<Outside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation }}>
|
||||||
{root === ROOT_OUTSIDE ? (
|
|
||||||
<Outside.Screen name='OnboardingView' component={OnboardingView} options={OnboardingView.navigationOptions} />
|
|
||||||
) : null}
|
|
||||||
<Outside.Screen name='NewServerView' component={NewServerView} options={NewServerView.navigationOptions} />
|
<Outside.Screen name='NewServerView' component={NewServerView} options={NewServerView.navigationOptions} />
|
||||||
<Outside.Screen name='WorkspaceView' component={WorkspaceView} options={WorkspaceView.navigationOptions} />
|
<Outside.Screen name='WorkspaceView' component={WorkspaceView} options={WorkspaceView.navigationOptions} />
|
||||||
<Outside.Screen name='LoginView' component={LoginView} options={LoginView.navigationOptions} />
|
<Outside.Screen name='LoginView' component={LoginView} options={LoginView.navigationOptions} />
|
||||||
|
@ -41,10 +35,6 @@ const mapStateToProps = state => ({
|
||||||
root: state.app.root
|
root: state.app.root
|
||||||
});
|
});
|
||||||
|
|
||||||
_OutsideStack.propTypes = {
|
|
||||||
root: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
const OutsideStack = connect(mapStateToProps)(_OutsideStack);
|
const OutsideStack = connect(mapStateToProps)(_OutsideStack);
|
||||||
|
|
||||||
// OutsideStackModal
|
// OutsideStackModal
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
export default {
|
export default {
|
||||||
// ONBOARDING VIEW
|
|
||||||
ONBOARD_JOIN_A_WORKSPACE: 'onboard_join_a_workspace',
|
|
||||||
ONBOARD_CREATE_NEW_WORKSPACE: 'onboard_create_new_workspace',
|
|
||||||
ONBOARD_CREATE_NEW_WORKSPACE_F: 'onboard_create_new_workspace_f',
|
|
||||||
|
|
||||||
// NEW SERVER VIEW
|
// NEW SERVER VIEW
|
||||||
NS_CONNECT_TO_WORKSPACE: 'ns_connect_to_workspace',
|
NS_CONNECT_TO_WORKSPACE: 'ns_connect_to_workspace',
|
||||||
NS_JOIN_OPEN_WORKSPACE: 'ns_join_open_workspace',
|
NS_JOIN_OPEN_WORKSPACE: 'ns_join_open_workspace',
|
||||||
|
@ -78,6 +73,8 @@ export default {
|
||||||
RL_GROUP_CHANNELS_BY_TYPE: 'rl_group_channels_by_type',
|
RL_GROUP_CHANNELS_BY_TYPE: 'rl_group_channels_by_type',
|
||||||
RL_GROUP_CHANNELS_BY_FAVORITE: 'rl_group_channels_by_favorite',
|
RL_GROUP_CHANNELS_BY_FAVORITE: 'rl_group_channels_by_favorite',
|
||||||
RL_GROUP_CHANNELS_BY_UNREAD: 'rl_group_channels_by_unread',
|
RL_GROUP_CHANNELS_BY_UNREAD: 'rl_group_channels_by_unread',
|
||||||
|
RL_CREATE_NEW_WORKSPACE: 'rl_create_new_workspace',
|
||||||
|
RL_CREATE_NEW_WORKSPACE_F: 'rl_create_new_workspace_f',
|
||||||
|
|
||||||
// QUEUE LIST VIEW
|
// QUEUE LIST VIEW
|
||||||
QL_GO_ROOM: 'ql_go_room',
|
QL_GO_ROOM: 'ql_go_room',
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
import { Dimensions } from 'react-native';
|
|
||||||
|
|
||||||
import { isTablet } from './deviceInfo';
|
import { isTablet } from './deviceInfo';
|
||||||
|
|
||||||
const { width, height } = Dimensions.get('window');
|
|
||||||
|
|
||||||
const guidelineBaseWidth = isTablet ? 600 : 375;
|
const guidelineBaseWidth = isTablet ? 600 : 375;
|
||||||
const guidelineBaseHeight = isTablet ? 800 : 667;
|
const guidelineBaseHeight = isTablet ? 800 : 667;
|
||||||
|
|
||||||
const scale = size => (width / guidelineBaseWidth) * size;
|
// TODO: we need to refactor this
|
||||||
const verticalScale = size => (height / guidelineBaseHeight) * size;
|
const scale = (size, width) => (width / guidelineBaseWidth) * size;
|
||||||
const moderateScale = (size, factor = 0.5) => size + (scale(size) - size) * factor;
|
const verticalScale = (size, height) => (height / guidelineBaseHeight) * size;
|
||||||
|
const moderateScale = (size, factor = 0.5, width) => size + (scale(size, width) - size) * factor;
|
||||||
|
|
||||||
export { scale, verticalScale, moderateScale };
|
export { scale, verticalScale, moderateScale };
|
||||||
|
|
|
@ -11,7 +11,6 @@ import Item from './Item';
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
marginTop: 24,
|
|
||||||
marginBottom: 32
|
marginBottom: 32
|
||||||
},
|
},
|
||||||
inputContainer: {
|
inputContainer: {
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { BackHandler, Keyboard, StyleSheet, Text, View } from 'react-native';
|
import { Text, Keyboard, StyleSheet, View, BackHandler, Image } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Base64 } from 'js-base64';
|
import { Base64 } from 'js-base64';
|
||||||
import parse from 'url-parse';
|
import parse from 'url-parse';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
import { TouchableOpacity } from 'react-native-gesture-handler';
|
import { TouchableOpacity } from 'react-native-gesture-handler';
|
||||||
|
import Orientation from 'react-native-orientation-locker';
|
||||||
|
|
||||||
import UserPreferences from '../../lib/userPreferences';
|
import UserPreferences from '../../lib/userPreferences';
|
||||||
import EventEmitter from '../../utils/events';
|
import EventEmitter from '../../utils/events';
|
||||||
import { selectServerRequest, serverRequest } from '../../actions/server';
|
import { selectServerRequest, serverRequest, serverFinishAdd as serverFinishAddAction } from '../../actions/server';
|
||||||
import { inviteLinksClear as inviteLinksClearAction } from '../../actions/inviteLinks';
|
import { inviteLinksClear as inviteLinksClearAction } from '../../actions/inviteLinks';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
import Button from '../../containers/Button';
|
import Button from '../../containers/Button';
|
||||||
|
@ -27,31 +28,39 @@ import database from '../../lib/database';
|
||||||
import { sanitizeLikeString } from '../../lib/database/utils';
|
import { sanitizeLikeString } from '../../lib/database/utils';
|
||||||
import SSLPinning from '../../utils/sslPinning';
|
import SSLPinning from '../../utils/sslPinning';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
import { isTablet } from '../../utils/deviceInfo';
|
||||||
|
import { verticalScale, moderateScale } from '../../utils/scaling';
|
||||||
|
import { withDimensions } from '../../dimensions';
|
||||||
import ServerInput from './ServerInput';
|
import ServerInput from './ServerInput';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
onboardingImage: {
|
||||||
|
alignSelf: 'center',
|
||||||
|
width: 100,
|
||||||
|
height: 100
|
||||||
|
},
|
||||||
title: {
|
title: {
|
||||||
...sharedStyles.textBold,
|
...sharedStyles.textBold,
|
||||||
fontSize: 22
|
letterSpacing: 0,
|
||||||
|
alignSelf: 'center'
|
||||||
|
},
|
||||||
|
subtitle: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
alignSelf: 'center'
|
||||||
},
|
},
|
||||||
certificatePicker: {
|
certificatePicker: {
|
||||||
marginBottom: 32,
|
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'flex-end'
|
justifyContent: 'flex-end'
|
||||||
},
|
},
|
||||||
chooseCertificateTitle: {
|
chooseCertificateTitle: {
|
||||||
fontSize: 13,
|
|
||||||
...sharedStyles.textRegular
|
...sharedStyles.textRegular
|
||||||
},
|
},
|
||||||
chooseCertificate: {
|
chooseCertificate: {
|
||||||
fontSize: 13,
|
|
||||||
...sharedStyles.textSemibold
|
...sharedStyles.textSemibold
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
...sharedStyles.textRegular,
|
...sharedStyles.textRegular,
|
||||||
fontSize: 14,
|
textAlign: 'center'
|
||||||
textAlign: 'left',
|
|
||||||
marginBottom: 24
|
|
||||||
},
|
},
|
||||||
connectButton: {
|
connectButton: {
|
||||||
marginBottom: 0
|
marginBottom: 0
|
||||||
|
@ -59,23 +68,22 @@ const styles = StyleSheet.create({
|
||||||
});
|
});
|
||||||
|
|
||||||
class NewServerView extends React.Component {
|
class NewServerView extends React.Component {
|
||||||
static navigationOptions = () => ({
|
|
||||||
title: I18n.t('Workspaces')
|
|
||||||
});
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigation: PropTypes.object,
|
navigation: PropTypes.object,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
connecting: PropTypes.bool.isRequired,
|
connecting: PropTypes.bool.isRequired,
|
||||||
connectServer: PropTypes.func.isRequired,
|
connectServer: PropTypes.func.isRequired,
|
||||||
selectServer: PropTypes.func.isRequired,
|
selectServer: PropTypes.func.isRequired,
|
||||||
adding: PropTypes.bool,
|
|
||||||
previousServer: PropTypes.string,
|
previousServer: PropTypes.string,
|
||||||
inviteLinksClear: PropTypes.func
|
inviteLinksClear: PropTypes.func,
|
||||||
|
serverFinishAdd: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
if (!isTablet) {
|
||||||
|
Orientation.lockToPortrait();
|
||||||
|
}
|
||||||
this.setHeader();
|
this.setHeader();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -92,25 +100,27 @@ class NewServerView extends React.Component {
|
||||||
this.queryServerHistory();
|
this.queryServerHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
|
||||||
const { adding } = this.props;
|
|
||||||
if (prevProps.adding !== adding) {
|
|
||||||
this.setHeader();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
EventEmitter.removeListener('NewServer', this.handleNewServerEvent);
|
EventEmitter.removeListener('NewServer', this.handleNewServerEvent);
|
||||||
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
|
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
|
||||||
|
const { previousServer, serverFinishAdd } = this.props;
|
||||||
|
if (previousServer) {
|
||||||
|
serverFinishAdd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setHeader = () => {
|
setHeader = () => {
|
||||||
const { adding, navigation } = this.props;
|
const { previousServer, navigation } = this.props;
|
||||||
if (adding) {
|
if (previousServer) {
|
||||||
navigation.setOptions({
|
return navigation.setOptions({
|
||||||
|
headerTitle: I18n.t('Workspaces'),
|
||||||
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} onPress={this.close} testID='new-server-view-close' />
|
headerLeft: () => <HeaderButton.CloseModal navigation={navigation} onPress={this.close} testID='new-server-view-close' />
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return navigation.setOptions({
|
||||||
|
headerShown: false
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleBackPress = () => {
|
handleBackPress = () => {
|
||||||
|
@ -273,16 +283,26 @@ class NewServerView extends React.Component {
|
||||||
|
|
||||||
renderCertificatePicker = () => {
|
renderCertificatePicker = () => {
|
||||||
const { certificate } = this.state;
|
const { certificate } = this.state;
|
||||||
const { theme } = this.props;
|
const { theme, width, height } = this.props;
|
||||||
return (
|
return (
|
||||||
<View style={styles.certificatePicker}>
|
<View
|
||||||
<Text style={[styles.chooseCertificateTitle, { color: themes[theme].auxiliaryText }]}>
|
style={[
|
||||||
|
styles.certificatePicker,
|
||||||
|
{
|
||||||
|
marginBottom: verticalScale(32, height)
|
||||||
|
}
|
||||||
|
]}>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.chooseCertificateTitle,
|
||||||
|
{ color: themes[theme].auxiliaryText, fontSize: moderateScale(13, null, width) }
|
||||||
|
]}>
|
||||||
{certificate ? I18n.t('Your_certificate') : I18n.t('Do_you_have_a_certificate')}
|
{certificate ? I18n.t('Your_certificate') : I18n.t('Do_you_have_a_certificate')}
|
||||||
</Text>
|
</Text>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={certificate ? this.handleRemove : this.chooseCertificate}
|
onPress={certificate ? this.handleRemove : this.chooseCertificate}
|
||||||
testID='new-server-choose-certificate'>
|
testID='new-server-choose-certificate'>
|
||||||
<Text style={[styles.chooseCertificate, { color: themes[theme].tintColor }]}>
|
<Text style={[styles.chooseCertificate, { color: themes[theme].tintColor, fontSize: moderateScale(13, null, width) }]}>
|
||||||
{certificate ?? I18n.t('Apply_Your_Certificate')}
|
{certificate ?? I18n.t('Apply_Your_Certificate')}
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
@ -291,12 +311,44 @@ class NewServerView extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { connecting, theme } = this.props;
|
const { connecting, theme, previousServer, width, height } = this.props;
|
||||||
const { text, connectingOpen, serversHistory } = this.state;
|
const { text, connectingOpen, serversHistory } = this.state;
|
||||||
|
const marginTopHeader = previousServer ? 0 : 70;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormContainer theme={theme} testID='new-server-view' keyboardShouldPersistTaps='never'>
|
<FormContainer theme={theme} testID='new-server-view' keyboardShouldPersistTaps='never'>
|
||||||
<FormContainerInner>
|
<FormContainerInner>
|
||||||
<Text style={[styles.title, { color: themes[theme].titleText }]}>{I18n.t('Join_your_workspace')}</Text>
|
<Image
|
||||||
|
style={[
|
||||||
|
styles.onboardingImage,
|
||||||
|
{
|
||||||
|
marginTop: isTablet ? 0 : verticalScale(marginTopHeader, height),
|
||||||
|
marginBottom: verticalScale(25, height),
|
||||||
|
maxHeight: verticalScale(150, height)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
source={require('../../static/images/logo.png')}
|
||||||
|
fadeDuration={0}
|
||||||
|
resizeMode='stretch'
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.title,
|
||||||
|
{ color: themes[theme].titleText, fontSize: moderateScale(22, null, width), marginBottom: verticalScale(8, height) }
|
||||||
|
]}>
|
||||||
|
Rocket.Chat
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.subtitle,
|
||||||
|
{
|
||||||
|
color: themes[theme].controlText,
|
||||||
|
fontSize: moderateScale(16, null, width),
|
||||||
|
marginBottom: verticalScale(41, height)
|
||||||
|
}
|
||||||
|
]}>
|
||||||
|
{I18n.t('Onboarding_subtitle')}
|
||||||
|
</Text>
|
||||||
<ServerInput
|
<ServerInput
|
||||||
text={text}
|
text={text}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
@ -317,7 +369,15 @@ class NewServerView extends React.Component {
|
||||||
testID='new-server-view-button'
|
testID='new-server-view-button'
|
||||||
/>
|
/>
|
||||||
<OrSeparator theme={theme} />
|
<OrSeparator theme={theme} />
|
||||||
<Text style={[styles.description, { color: themes[theme].auxiliaryText }]}>
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.description,
|
||||||
|
{
|
||||||
|
color: themes[theme].auxiliaryText,
|
||||||
|
fontSize: moderateScale(14, null, width),
|
||||||
|
marginBottom: verticalScale(24, height)
|
||||||
|
}
|
||||||
|
]}>
|
||||||
{I18n.t('Onboarding_join_open_description')}
|
{I18n.t('Onboarding_join_open_description')}
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
|
@ -339,14 +399,14 @@ class NewServerView extends React.Component {
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
connecting: state.server.connecting,
|
connecting: state.server.connecting,
|
||||||
adding: state.server.adding,
|
|
||||||
previousServer: state.server.previousServer
|
previousServer: state.server.previousServer
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
connectServer: (...params) => dispatch(serverRequest(...params)),
|
connectServer: (...params) => dispatch(serverRequest(...params)),
|
||||||
selectServer: server => dispatch(selectServerRequest(server)),
|
selectServer: server => dispatch(selectServerRequest(server)),
|
||||||
inviteLinksClear: () => dispatch(inviteLinksClearAction())
|
inviteLinksClear: () => dispatch(inviteLinksClearAction()),
|
||||||
|
serverFinishAdd: () => dispatch(serverFinishAddAction())
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(NewServerView));
|
export default connect(mapStateToProps, mapDispatchToProps)(withDimensions(withTheme(NewServerView)));
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Image, Linking, Text, View } from 'react-native';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import Orientation from 'react-native-orientation-locker';
|
|
||||||
|
|
||||||
import I18n from '../../i18n';
|
|
||||||
import Button from '../../containers/Button';
|
|
||||||
import { isTablet } from '../../utils/deviceInfo';
|
|
||||||
import { themes } from '../../constants/colors';
|
|
||||||
import { withTheme } from '../../theme';
|
|
||||||
import FormContainer, { FormContainerInner } from '../../containers/FormContainer';
|
|
||||||
import { events, logEvent } from '../../utils/log';
|
|
||||||
import styles from './styles';
|
|
||||||
|
|
||||||
class OnboardingView extends React.Component {
|
|
||||||
static navigationOptions = {
|
|
||||||
headerShown: false
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
navigation: PropTypes.object,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
if (!isTablet) {
|
|
||||||
Orientation.lockToPortrait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
|
||||||
const { theme } = this.props;
|
|
||||||
if (theme !== nextProps.theme) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
connectServer = () => {
|
|
||||||
logEvent(events.ONBOARD_JOIN_A_WORKSPACE);
|
|
||||||
const { navigation } = this.props;
|
|
||||||
navigation.navigate('NewServerView');
|
|
||||||
};
|
|
||||||
|
|
||||||
createWorkspace = async () => {
|
|
||||||
logEvent(events.ONBOARD_CREATE_NEW_WORKSPACE);
|
|
||||||
try {
|
|
||||||
await Linking.openURL('https://cloud.rocket.chat/trial');
|
|
||||||
} catch {
|
|
||||||
logEvent(events.ONBOARD_CREATE_NEW_WORKSPACE_F);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { theme } = this.props;
|
|
||||||
return (
|
|
||||||
<FormContainer theme={theme} testID='onboarding-view'>
|
|
||||||
<FormContainerInner>
|
|
||||||
<Image style={styles.onboarding} source={require('../../static/images/logo.png')} fadeDuration={0} />
|
|
||||||
<Text style={[styles.title, { color: themes[theme].titleText }]}>{I18n.t('Onboarding_title')}</Text>
|
|
||||||
<Text style={[styles.subtitle, { color: themes[theme].controlText }]}>{I18n.t('Onboarding_subtitle')}</Text>
|
|
||||||
<Text style={[styles.description, { color: themes[theme].auxiliaryText }]}>{I18n.t('Onboarding_description')}</Text>
|
|
||||||
<View style={styles.buttonsContainer}>
|
|
||||||
<Button
|
|
||||||
title={I18n.t('Onboarding_join_workspace')}
|
|
||||||
type='primary'
|
|
||||||
onPress={this.connectServer}
|
|
||||||
theme={theme}
|
|
||||||
testID='join-workspace'
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
title={I18n.t('Create_a_new_workspace')}
|
|
||||||
type='secondary'
|
|
||||||
backgroundColor={themes[theme].chatComponentBackground}
|
|
||||||
onPress={this.createWorkspace}
|
|
||||||
theme={theme}
|
|
||||||
testID='create-workspace-button'
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</FormContainerInner>
|
|
||||||
</FormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withTheme(OnboardingView);
|
|
|
@ -1,41 +0,0 @@
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import { moderateScale, verticalScale } from '../../utils/scaling';
|
|
||||||
import { isTablet } from '../../utils/deviceInfo';
|
|
||||||
import sharedStyles from '../Styles';
|
|
||||||
|
|
||||||
export default StyleSheet.create({
|
|
||||||
onboarding: {
|
|
||||||
alignSelf: 'center',
|
|
||||||
marginTop: isTablet ? 0 : verticalScale(116),
|
|
||||||
marginBottom: verticalScale(50),
|
|
||||||
maxHeight: verticalScale(150),
|
|
||||||
resizeMode: 'contain',
|
|
||||||
width: 100,
|
|
||||||
height: 100
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
...sharedStyles.textBold,
|
|
||||||
letterSpacing: 0,
|
|
||||||
fontSize: moderateScale(24),
|
|
||||||
alignSelf: 'center',
|
|
||||||
marginBottom: verticalScale(8)
|
|
||||||
},
|
|
||||||
subtitle: {
|
|
||||||
...sharedStyles.textRegular,
|
|
||||||
fontSize: moderateScale(16),
|
|
||||||
alignSelf: 'center',
|
|
||||||
marginBottom: verticalScale(24)
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
...sharedStyles.textRegular,
|
|
||||||
...sharedStyles.textAlignCenter,
|
|
||||||
fontSize: moderateScale(14),
|
|
||||||
alignSelf: 'center',
|
|
||||||
marginHorizontal: 20
|
|
||||||
},
|
|
||||||
buttonsContainer: {
|
|
||||||
marginBottom: verticalScale(10),
|
|
||||||
marginTop: verticalScale(30)
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,13 +1,14 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Animated, Easing, FlatList, Text, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native';
|
import { View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Linking } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { batch, connect } from 'react-redux';
|
import { batch, connect } from 'react-redux';
|
||||||
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
import * as List from '../../containers/List';
|
import * as List from '../../containers/List';
|
||||||
|
import Button from '../../containers/Button';
|
||||||
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
|
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
|
||||||
import { selectServerRequest as selectServerRequestAction, serverInitAdd as serverInitAddAction } from '../../actions/server';
|
import { selectServerRequest as selectServerRequestAction, serverInitAdd as serverInitAddAction } from '../../actions/server';
|
||||||
import { ROOT_NEW_SERVER, appStart as appStartAction } from '../../actions/app';
|
import { appStart as appStartAction, ROOT_OUTSIDE } from '../../actions/app';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import EventEmitter from '../../utils/events';
|
import EventEmitter from '../../utils/events';
|
||||||
|
@ -19,7 +20,7 @@ import { KEY_COMMAND, handleCommandSelectServer } from '../../commands';
|
||||||
import { isTablet } from '../../utils/deviceInfo';
|
import { isTablet } from '../../utils/deviceInfo';
|
||||||
import { localAuthenticate } from '../../utils/localAuthentication';
|
import { localAuthenticate } from '../../utils/localAuthentication';
|
||||||
import { showConfirmationAlert } from '../../utils/info';
|
import { showConfirmationAlert } from '../../utils/info';
|
||||||
import { events, logEvent } from '../../utils/log';
|
import log, { events, logEvent } from '../../utils/log';
|
||||||
import { headerHeight } from '../../containers/Header';
|
import { headerHeight } from '../../containers/Header';
|
||||||
import { goRoom } from '../../utils/goRoom';
|
import { goRoom } from '../../utils/goRoom';
|
||||||
import UserPreferences from '../../lib/userPreferences';
|
import UserPreferences from '../../lib/userPreferences';
|
||||||
|
@ -97,10 +98,19 @@ class ServerDropdown extends Component {
|
||||||
}).start(() => toggleServerDropdown());
|
}).start(() => toggleServerDropdown());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
createWorkspace = async () => {
|
||||||
|
logEvent(events.RL_CREATE_NEW_WORKSPACE);
|
||||||
|
try {
|
||||||
|
await Linking.openURL('https://cloud.rocket.chat/trial');
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
navToNewServer = previousServer => {
|
navToNewServer = previousServer => {
|
||||||
const { appStart, initAdd } = this.props;
|
const { appStart, initAdd } = this.props;
|
||||||
batch(() => {
|
batch(() => {
|
||||||
appStart({ root: ROOT_NEW_SERVER });
|
appStart({ root: ROOT_OUTSIDE });
|
||||||
initAdd(previousServer);
|
initAdd(previousServer);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -181,7 +191,7 @@ class ServerDropdown extends Component {
|
||||||
const { servers } = this.state;
|
const { servers } = this.state;
|
||||||
const { theme, isMasterDetail, insets } = this.props;
|
const { theme, isMasterDetail, insets } = this.props;
|
||||||
const maxRows = 4;
|
const maxRows = 4;
|
||||||
const initialTop = 41 + Math.min(servers.length, maxRows) * ROW_HEIGHT;
|
const initialTop = 87 + Math.min(servers.length, maxRows) * ROW_HEIGHT;
|
||||||
const statusBarHeight = insets?.top ?? 0;
|
const statusBarHeight = insets?.top ?? 0;
|
||||||
const heightDestination = isMasterDetail ? headerHeight + statusBarHeight : 0;
|
const heightDestination = isMasterDetail ? headerHeight + statusBarHeight : 0;
|
||||||
const translateY = this.animatedValue.interpolate({
|
const translateY = this.animatedValue.interpolate({
|
||||||
|
@ -230,6 +240,17 @@ class ServerDropdown extends Component {
|
||||||
ItemSeparatorComponent={List.Separator}
|
ItemSeparatorComponent={List.Separator}
|
||||||
keyboardShouldPersistTaps='always'
|
keyboardShouldPersistTaps='always'
|
||||||
/>
|
/>
|
||||||
|
<List.Separator />
|
||||||
|
<Button
|
||||||
|
title={I18n.t('Create_a_new_workspace')}
|
||||||
|
type='secondary'
|
||||||
|
onPress={this.createWorkspace}
|
||||||
|
theme={theme}
|
||||||
|
testID='rooms-list-header-create-workspace-button'
|
||||||
|
style={styles.buttonCreateWorkspace}
|
||||||
|
color={themes[theme].tintColor}
|
||||||
|
styleText={[styles.serverHeaderAdd, { textAlign: 'center' }]}
|
||||||
|
/>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { BackHandler, FlatList, Keyboard, RefreshControl, Text, View } from 'react-native';
|
import { BackHandler, FlatList, Keyboard, RefreshControl, Text, View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { batch, connect } from 'react-redux';
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
import Orientation from 'react-native-orientation-locker';
|
import Orientation from 'react-native-orientation-locker';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
@ -19,12 +19,13 @@ import {
|
||||||
roomsRequest as roomsRequestAction,
|
roomsRequest as roomsRequestAction,
|
||||||
toggleSortDropdown as toggleSortDropdownAction
|
toggleSortDropdown as toggleSortDropdownAction
|
||||||
} from '../../actions/rooms';
|
} from '../../actions/rooms';
|
||||||
|
import { appStart as appStartAction, ROOT_OUTSIDE } from '../../actions/app';
|
||||||
import debounce from '../../utils/debounce';
|
import debounce from '../../utils/debounce';
|
||||||
import { isIOS, isTablet } from '../../utils/deviceInfo';
|
import { isIOS, isTablet } from '../../utils/deviceInfo';
|
||||||
import * as HeaderButton from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
import { selectServerRequest as selectServerRequestAction, serverInitAdd as serverInitAddAction } from '../../actions/server';
|
||||||
import { animateNextTransition } from '../../utils/layoutAnimation';
|
import { animateNextTransition } from '../../utils/layoutAnimation';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
@ -133,7 +134,8 @@ class RoomsListView extends React.Component {
|
||||||
insets: PropTypes.object,
|
insets: PropTypes.object,
|
||||||
queueSize: PropTypes.number,
|
queueSize: PropTypes.number,
|
||||||
inquiryEnabled: PropTypes.bool,
|
inquiryEnabled: PropTypes.bool,
|
||||||
encryptionBanner: PropTypes.string
|
encryptionBanner: PropTypes.string,
|
||||||
|
initAdd: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -763,7 +765,7 @@ class RoomsListView extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCommands = ({ event }) => {
|
handleCommands = ({ event }) => {
|
||||||
const { navigation, server, isMasterDetail } = this.props;
|
const { navigation, server, isMasterDetail, appStart, initAdd } = this.props;
|
||||||
const { input } = event;
|
const { input } = event;
|
||||||
if (handleCommandShowPreferences(event)) {
|
if (handleCommandShowPreferences(event)) {
|
||||||
navigation.navigate('SettingsView');
|
navigation.navigate('SettingsView');
|
||||||
|
@ -782,7 +784,10 @@ class RoomsListView extends React.Component {
|
||||||
navigation.navigate('NewMessageStack');
|
navigation.navigate('NewMessageStack');
|
||||||
}
|
}
|
||||||
} else if (handleCommandAddNewServer(event)) {
|
} else if (handleCommandAddNewServer(event)) {
|
||||||
navigation.navigate('NewServerView', { previousServer: server });
|
batch(() => {
|
||||||
|
appStart({ root: ROOT_OUTSIDE });
|
||||||
|
initAdd(server);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -967,7 +972,9 @@ const mapDispatchToProps = dispatch => ({
|
||||||
closeSearchHeader: () => dispatch(closeSearchHeaderAction()),
|
closeSearchHeader: () => dispatch(closeSearchHeaderAction()),
|
||||||
roomsRequest: params => dispatch(roomsRequestAction(params)),
|
roomsRequest: params => dispatch(roomsRequestAction(params)),
|
||||||
selectServerRequest: server => dispatch(selectServerRequestAction(server)),
|
selectServerRequest: server => dispatch(selectServerRequestAction(server)),
|
||||||
closeServerDropdown: () => dispatch(closeServerDropdownAction())
|
closeServerDropdown: () => dispatch(closeServerDropdownAction()),
|
||||||
|
appStart: params => dispatch(appStartAction(params)),
|
||||||
|
initAdd: previousServer => dispatch(serverInitAddAction(previousServer))
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomsListView))));
|
export default connect(mapStateToProps, mapDispatchToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomsListView))));
|
||||||
|
|
|
@ -56,5 +56,10 @@ export default StyleSheet.create({
|
||||||
marginRight: 12,
|
marginRight: 12,
|
||||||
paddingVertical: 10,
|
paddingVertical: 10,
|
||||||
...sharedStyles.textRegular
|
...sharedStyles.textRegular
|
||||||
|
},
|
||||||
|
buttonCreateWorkspace: {
|
||||||
|
height: 46,
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginBottom: 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -96,7 +96,6 @@ class WorkspaceView extends React.Component {
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
server: state.server.server,
|
server: state.server.server,
|
||||||
adding: state.server.adding,
|
|
||||||
Site_Name: state.settings.Site_Name,
|
Site_Name: state.settings.Site_Name,
|
||||||
Site_Url: state.settings.Site_Url,
|
Site_Url: state.settings.Site_Url,
|
||||||
Assets_favicon_512: state.settings.Assets_favicon_512,
|
Assets_favicon_512: state.settings.Assets_favicon_512,
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
const data = require('../data');
|
const data = require('../data');
|
||||||
|
|
||||||
async function navigateToWorkspace(server = data.server) {
|
async function navigateToWorkspace(server = data.server) {
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(10000);
|
|
||||||
await element(by.id('join-workspace')).tap();
|
|
||||||
await waitFor(element(by.id('new-server-view')))
|
await waitFor(element(by.id('new-server-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(60000);
|
.withTimeout(60000);
|
||||||
|
@ -16,9 +12,6 @@ async function navigateToWorkspace(server = data.server) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function navigateToLogin(server) {
|
async function navigateToLogin(server) {
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(20000);
|
|
||||||
await navigateToWorkspace(server);
|
await navigateToWorkspace(server);
|
||||||
await element(by.id('workspace-view-login')).tap();
|
await element(by.id('workspace-view-login')).tap();
|
||||||
await waitFor(element(by.id('login-view')))
|
await waitFor(element(by.id('login-view')))
|
||||||
|
@ -28,9 +21,6 @@ async function navigateToLogin(server) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function navigateToRegister(server) {
|
async function navigateToRegister(server) {
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(20000);
|
|
||||||
await navigateToWorkspace(server);
|
await navigateToWorkspace(server);
|
||||||
await element(by.id('workspace-view-register')).tap();
|
await element(by.id('workspace-view-register')).tap();
|
||||||
await waitFor(element(by.id('register-view')))
|
await waitFor(element(by.id('register-view')))
|
||||||
|
@ -70,10 +60,10 @@ async function logout() {
|
||||||
.withTimeout(10000);
|
.withTimeout(10000);
|
||||||
await expect(element(by.text(logoutAlertMessage)).atIndex(0)).toExist();
|
await expect(element(by.text(logoutAlertMessage)).atIndex(0)).toExist();
|
||||||
await element(by.text('Logout')).tap();
|
await element(by.text('Logout')).tap();
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
await waitFor(element(by.id('new-server-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(10000);
|
.withTimeout(10000);
|
||||||
await expect(element(by.id('onboarding-view'))).toBeVisible();
|
await expect(element(by.id('new-server-view'))).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function mockMessage(message, isThread = false) {
|
async function mockMessage(message, isThread = false) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ const reopenAndCheckServer = async server => {
|
||||||
await device.launchApp({ permissions: { notifications: 'YES' } });
|
await device.launchApp({ permissions: { notifications: 'YES' } });
|
||||||
await waitFor(element(by.id('rooms-list-view')))
|
await waitFor(element(by.id('rooms-list-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(6000);
|
.withTimeout(10000);
|
||||||
await checkServer(server);
|
await checkServer(server);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,13 +19,21 @@ describe('Change server', () => {
|
||||||
.withTimeout(10000);
|
.withTimeout(10000);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should login to server, add new server, close the app, open the app and show previous logged server', async () => {
|
it('should open the dropdown button, have the server add button and create workspace button', async () => {
|
||||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(5000);
|
.withTimeout(5000);
|
||||||
await element(by.id('rooms-list-header-server-add')).tap();
|
await waitFor(element(by.id('rooms-list-header-server-add')))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(5000);
|
||||||
|
await waitFor(element(by.id('rooms-list-header-create-workspace-button')))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(5000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should login to server, add new server, close the app, open the app and show previous logged server', async () => {
|
||||||
|
await element(by.id('rooms-list-header-server-add')).tap();
|
||||||
await waitFor(element(by.id('new-server-view')))
|
await waitFor(element(by.id('new-server-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(6000);
|
.withTimeout(6000);
|
||||||
|
|
|
@ -37,11 +37,10 @@ describe('i18n', () => {
|
||||||
},
|
},
|
||||||
delete: true
|
delete: true
|
||||||
});
|
});
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
await waitFor(element(by.id('new-server-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(20000);
|
.withTimeout(20000);
|
||||||
await expect(element(by.id('join-workspace').and(by.label('Join a workspace')))).toBeVisible();
|
await expect(element(by.id('new-server-view-open').and(by.label('Join our open workspace')))).toBeVisible();
|
||||||
await expect(element(by.id('create-workspace-button').and(by.label('Create a new workspace')))).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("OS set to unavailable language and fallback to 'en'", async () => {
|
it("OS set to unavailable language and fallback to 'en'", async () => {
|
||||||
|
@ -52,11 +51,10 @@ describe('i18n', () => {
|
||||||
locale: 'es-MX'
|
locale: 'es-MX'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
await waitFor(element(by.id('new-server-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(20000);
|
.withTimeout(20000);
|
||||||
await expect(element(by.id('join-workspace').and(by.label('Join a workspace')))).toBeVisible();
|
await expect(element(by.id('new-server-view-open').and(by.label('Join our open workspace')))).toBeVisible();
|
||||||
await expect(element(by.id('create-workspace-button').and(by.label('Create a new workspace')))).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,9 +69,6 @@ describe('i18n', () => {
|
||||||
// locale: "nl"
|
// locale: "nl"
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
// await waitFor(element(by.id('onboarding-view'))).toBeVisible().withTimeout(20000);
|
|
||||||
// await expect(element(by.id('join-workspace').and(by.label('Word lid van een werkruimte')))).toBeVisible();
|
|
||||||
// await expect(element(by.id('create-workspace-button').and(by.label('Een nieuwe werkruimte aanmaken')))).toBeVisible();
|
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,22 +3,18 @@ const data = require('../../data');
|
||||||
describe('Onboarding', () => {
|
describe('Onboarding', () => {
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
await waitFor(element(by.id('new-server-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(20000);
|
.withTimeout(20000);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Render', () => {
|
describe('Render', () => {
|
||||||
it('should have onboarding screen', async () => {
|
it('should have onboarding screen', async () => {
|
||||||
await expect(element(by.id('onboarding-view'))).toBeVisible();
|
await expect(element(by.id('new-server-view'))).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have "Join a workspace"', async () => {
|
it('should have "Join our open workspace"', async () => {
|
||||||
await expect(element(by.id('join-workspace'))).toBeVisible();
|
await expect(element(by.id('new-server-view-open'))).toBeVisible();
|
||||||
});
|
|
||||||
|
|
||||||
it('should have "Create a new workspace"', async () => {
|
|
||||||
await expect(element(by.id('create-workspace-button'))).toBeVisible();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,13 +23,6 @@ describe('Onboarding', () => {
|
||||||
// // webviews are not supported by detox: https://github.com/wix/detox/issues/136#issuecomment-306591554
|
// // webviews are not supported by detox: https://github.com/wix/detox/issues/136#issuecomment-306591554
|
||||||
// });
|
// });
|
||||||
|
|
||||||
it('should navigate to join a workspace', async () => {
|
|
||||||
await element(by.id('join-workspace')).tap();
|
|
||||||
await waitFor(element(by.id('new-server-view')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(60000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should enter an invalid server and get error', async () => {
|
it('should enter an invalid server and get error', async () => {
|
||||||
await element(by.id('new-server-view-input')).typeText('invalidtest\n');
|
await element(by.id('new-server-view-input')).typeText('invalidtest\n');
|
||||||
const errorText = 'Oops!';
|
const errorText = 'Oops!';
|
||||||
|
@ -52,13 +41,9 @@ describe('Onboarding', () => {
|
||||||
|
|
||||||
it('should enter a valid server without login services and navigate to login', async () => {
|
it('should enter a valid server without login services and navigate to login', async () => {
|
||||||
await device.launchApp({ newInstance: true });
|
await device.launchApp({ newInstance: true });
|
||||||
await waitFor(element(by.id('onboarding-view')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(2000);
|
|
||||||
await element(by.id('join-workspace')).tap();
|
|
||||||
await waitFor(element(by.id('new-server-view')))
|
await waitFor(element(by.id('new-server-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(60000);
|
.withTimeout(5000);
|
||||||
await element(by.id('new-server-view-input')).typeText(`${data.server}\n`);
|
await element(by.id('new-server-view-input')).typeText(`${data.server}\n`);
|
||||||
await waitFor(element(by.id('workspace-view')))
|
await waitFor(element(by.id('workspace-view')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
|
|
Loading…
Reference in New Issue