Chore: Migrate redux module login to typescript (#3647)
* chore: migrate redux module login to typescript chore: update redux module login tests * update workers * wip * fix type * remove partial * add more status * migrate the rest of the stuff to typescript * fix tests and types * fix types and tests
This commit is contained in:
parent
d73886bd60
commit
219462ba3d
|
@ -1,59 +0,0 @@
|
|||
import * as types from './actionsTypes';
|
||||
|
||||
export function loginRequest(credentials, logoutOnError, isFromWebView) {
|
||||
return {
|
||||
type: types.LOGIN.REQUEST,
|
||||
credentials,
|
||||
logoutOnError,
|
||||
isFromWebView
|
||||
};
|
||||
}
|
||||
|
||||
export function loginSuccess(user) {
|
||||
return {
|
||||
type: types.LOGIN.SUCCESS,
|
||||
user
|
||||
};
|
||||
}
|
||||
|
||||
export function loginFailure(err) {
|
||||
return {
|
||||
type: types.LOGIN.FAILURE,
|
||||
err
|
||||
};
|
||||
}
|
||||
|
||||
export function logout(forcedByServer = false) {
|
||||
return {
|
||||
type: types.LOGOUT,
|
||||
forcedByServer
|
||||
};
|
||||
}
|
||||
|
||||
export function setUser(user) {
|
||||
return {
|
||||
type: types.USER.SET,
|
||||
user
|
||||
};
|
||||
}
|
||||
|
||||
export function setLoginServices(data) {
|
||||
return {
|
||||
type: types.LOGIN.SET_SERVICES,
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
export function setPreference(preference) {
|
||||
return {
|
||||
type: types.LOGIN.SET_PREFERENCE,
|
||||
preference
|
||||
};
|
||||
}
|
||||
|
||||
export function setLocalAuthenticated(isLocalAuthenticated) {
|
||||
return {
|
||||
type: types.LOGIN.SET_LOCAL_AUTHENTICATED,
|
||||
isLocalAuthenticated
|
||||
};
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
import { Action } from 'redux';
|
||||
|
||||
import { IUser } from '../definitions';
|
||||
import * as types from './actionsTypes';
|
||||
|
||||
interface ICredentials {
|
||||
resume: string;
|
||||
user: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface ILoginRequest extends Action {
|
||||
credentials: any;
|
||||
logoutOnError?: boolean;
|
||||
isFromWebView?: boolean;
|
||||
}
|
||||
|
||||
interface ILoginSuccess extends Action {
|
||||
user: Partial<IUser>;
|
||||
}
|
||||
|
||||
interface ILoginFailure extends Action {
|
||||
err: Partial<IUser>;
|
||||
}
|
||||
|
||||
interface ILogout extends Action {
|
||||
forcedByServer: boolean;
|
||||
}
|
||||
|
||||
interface ISetUser extends Action {
|
||||
user: Partial<IUser>;
|
||||
}
|
||||
|
||||
interface ISetServices extends Action {
|
||||
data: Record<string, string>;
|
||||
}
|
||||
|
||||
interface ISetPreference extends Action {
|
||||
preference: Record<string, any>;
|
||||
}
|
||||
|
||||
interface ISetLocalAuthenticated extends Action {
|
||||
isLocalAuthenticated: boolean;
|
||||
}
|
||||
|
||||
export type TActionsLogin = ILoginRequest &
|
||||
ILoginSuccess &
|
||||
ILoginFailure &
|
||||
ILogout &
|
||||
ISetUser &
|
||||
ISetServices &
|
||||
ISetPreference &
|
||||
ISetLocalAuthenticated;
|
||||
|
||||
export function loginRequest(
|
||||
credentials: Partial<ICredentials>,
|
||||
logoutOnError?: boolean,
|
||||
isFromWebView?: boolean
|
||||
): ILoginRequest {
|
||||
return {
|
||||
type: types.LOGIN.REQUEST,
|
||||
credentials,
|
||||
logoutOnError,
|
||||
isFromWebView
|
||||
};
|
||||
}
|
||||
|
||||
export function loginSuccess(user: Partial<IUser>): ILoginSuccess {
|
||||
return {
|
||||
type: types.LOGIN.SUCCESS,
|
||||
user
|
||||
};
|
||||
}
|
||||
|
||||
export function loginFailure(err: Record<string, any>): ILoginFailure {
|
||||
return {
|
||||
type: types.LOGIN.FAILURE,
|
||||
err
|
||||
};
|
||||
}
|
||||
|
||||
export function logout(forcedByServer = false): ILogout {
|
||||
return {
|
||||
type: types.LOGOUT,
|
||||
forcedByServer
|
||||
};
|
||||
}
|
||||
|
||||
export function setUser(user: Partial<IUser>): ISetUser {
|
||||
return {
|
||||
type: types.USER.SET,
|
||||
user
|
||||
};
|
||||
}
|
||||
|
||||
export function setLoginServices(data: Record<string, any>): ISetServices {
|
||||
return {
|
||||
type: types.LOGIN.SET_SERVICES,
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
export function setPreference(preference: Record<string, any>): ISetPreference {
|
||||
return {
|
||||
type: types.LOGIN.SET_PREFERENCE,
|
||||
preference
|
||||
};
|
||||
}
|
||||
|
||||
export function setLocalAuthenticated(isLocalAuthenticated: boolean): ISetLocalAuthenticated {
|
||||
return {
|
||||
type: types.LOGIN.SET_LOCAL_AUTHENTICATED,
|
||||
isLocalAuthenticated
|
||||
};
|
||||
}
|
|
@ -2,6 +2,7 @@ import Model from '@nozbe/watermelondb/Model';
|
|||
|
||||
import { UserStatus } from './UserStatus';
|
||||
import { IRocketChatRecord } from './IRocketChatRecord';
|
||||
import { ILoggedUser } from './ILoggedUser';
|
||||
|
||||
export interface ILoginToken {
|
||||
hashedToken: string;
|
||||
|
@ -93,8 +94,10 @@ export interface IUserSettings {
|
|||
};
|
||||
}
|
||||
|
||||
export interface IUser extends IRocketChatRecord {
|
||||
export interface IUser extends IRocketChatRecord, Omit<ILoggedUser, 'username' | 'name' | 'status'> {
|
||||
_id: string;
|
||||
id: string;
|
||||
token: string;
|
||||
createdAt: Date;
|
||||
roles: string[];
|
||||
type: string;
|
||||
|
|
|
@ -23,6 +23,7 @@ import { ICreateChannel } from '../../reducers/createChannel';
|
|||
import { ICreateDiscussion } from '../../reducers/createDiscussion';
|
||||
import { IEncryption } from '../../reducers/encryption';
|
||||
import { IInviteLinks } from '../../reducers/inviteLinks';
|
||||
import { ILogin } from '../../reducers/login';
|
||||
import { IRoles } from '../../reducers/roles';
|
||||
import { IRoom } from '../../reducers/room';
|
||||
import { ISelectedUsers } from '../../reducers/selectedUsers';
|
||||
|
@ -34,8 +35,8 @@ import { IEnterpriseModules } from '../../reducers/enterpriseModules';
|
|||
|
||||
export interface IApplicationState {
|
||||
settings: ISettings;
|
||||
login: any;
|
||||
meteor: IConnect;
|
||||
login: ILogin;
|
||||
server: IServer;
|
||||
selectedUsers: ISelectedUsers;
|
||||
app: IApp;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { clearActiveUsers, setActiveUsers } from '../actions/activeUsers';
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import { IActiveUsers, initialState } from './activeUsers';
|
||||
import { mockedStore } from './mockedStore';
|
||||
|
||||
|
@ -8,7 +9,7 @@ describe('test reducer', () => {
|
|||
expect(state).toEqual(initialState);
|
||||
});
|
||||
it('should return modified store after action', () => {
|
||||
const activeUsers: IActiveUsers = { any: { status: 'online', statusText: 'any' } };
|
||||
const activeUsers: IActiveUsers = { any: { status: UserStatus.ONLINE, statusText: 'any' } };
|
||||
mockedStore.dispatch(setActiveUsers(activeUsers));
|
||||
const state = mockedStore.getState().activeUsers;
|
||||
expect(state).toEqual({ ...activeUsers });
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { TApplicationActions } from '../definitions';
|
||||
import { ACTIVE_USERS } from '../actions/actionsTypes';
|
||||
import { TApplicationActions } from '../definitions';
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
|
||||
type TUserStatus = 'online' | 'offline' | 'away' | 'busy';
|
||||
export interface IActiveUser {
|
||||
status: TUserStatus;
|
||||
status: UserStatus;
|
||||
statusText: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
import {
|
||||
loginFailure,
|
||||
loginRequest,
|
||||
loginSuccess,
|
||||
logout,
|
||||
setLocalAuthenticated,
|
||||
setLoginServices,
|
||||
setUser
|
||||
} from '../actions/login';
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import { initialState } from './login';
|
||||
import { mockedStore } from './mockedStore';
|
||||
|
||||
describe('test selectedUsers reducer', () => {
|
||||
it('should return initial state', () => {
|
||||
const state = mockedStore.getState().login;
|
||||
expect(state).toEqual(initialState);
|
||||
});
|
||||
|
||||
it('should return modified store after loginRequest', () => {
|
||||
mockedStore.dispatch(loginRequest({ user: 'carlitos@email.com', password: '123456' }));
|
||||
const state = mockedStore.getState().login;
|
||||
expect(state).toEqual({ ...initialState, isFetching: true, isAuthenticated: false, failure: false, error: {} });
|
||||
});
|
||||
|
||||
it('should return modified store after loginFailure', () => {
|
||||
mockedStore.dispatch(loginFailure({ error: 'error' }));
|
||||
const state = mockedStore.getState().login.error.error;
|
||||
expect(state).toEqual('error');
|
||||
});
|
||||
|
||||
it('should return modified store after loginSuccess', () => {
|
||||
const user = {
|
||||
id: 'ajhsiahsa',
|
||||
token: 'asdasdasdas',
|
||||
username: 'carlitos',
|
||||
name: 'Carlitos',
|
||||
customFields: {
|
||||
phonenumber: ''
|
||||
},
|
||||
emails: [
|
||||
{
|
||||
address: 'carlitos@email.com',
|
||||
verified: true
|
||||
}
|
||||
],
|
||||
roles: ['user'],
|
||||
isFromWebView: false,
|
||||
showMessageInMainThread: false,
|
||||
enableMessageParserEarlyAdoption: false,
|
||||
status: UserStatus.ONLINE,
|
||||
statusText: 'online'
|
||||
};
|
||||
mockedStore.dispatch(loginSuccess(user));
|
||||
const state = mockedStore.getState().login.user;
|
||||
expect(state).toEqual(user);
|
||||
});
|
||||
|
||||
it('should return modified store after setUser', () => {
|
||||
const user = {
|
||||
id: 'ajhsiahsa',
|
||||
token: 'asdasdasdas',
|
||||
username: 'carlito',
|
||||
name: 'Carlitos',
|
||||
customFields: {
|
||||
phonenumber: ''
|
||||
},
|
||||
emails: [
|
||||
{
|
||||
address: 'carlitos@email.com',
|
||||
verified: true
|
||||
}
|
||||
],
|
||||
roles: ['user'],
|
||||
isFromWebView: false,
|
||||
showMessageInMainThread: false,
|
||||
enableMessageParserEarlyAdoption: false
|
||||
};
|
||||
mockedStore.dispatch(setUser(user));
|
||||
const state = mockedStore.getState().login.user.username;
|
||||
expect(state).toEqual(user.username);
|
||||
});
|
||||
|
||||
// TODO PREFERENCE REDUCER WITH EMPTY PREFERENCE - NON USED?
|
||||
// it('should return modified store after setPreference', () => {
|
||||
// mockedStore.dispatch(setPreference({ showAvatar: true }));
|
||||
// const state = mockedStore.getState().login;
|
||||
// console.log(state);
|
||||
// expect(state).toEqual('error');
|
||||
// });
|
||||
|
||||
it('should return modified store after setLocalAuthenticated', () => {
|
||||
mockedStore.dispatch(setLocalAuthenticated(true));
|
||||
const state = mockedStore.getState().login.isLocalAuthenticated;
|
||||
expect(state).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return modified store after setLoginServices', () => {
|
||||
mockedStore.dispatch(setLoginServices({ facebook: { clientId: 'xxx' } }));
|
||||
const state = mockedStore.getState().login.services.facebook.clientId;
|
||||
expect(state).toEqual('xxx');
|
||||
});
|
||||
|
||||
it('should return modified store after logout', () => {
|
||||
mockedStore.dispatch(logout());
|
||||
const state = mockedStore.getState().login;
|
||||
expect(state).toEqual(initialState);
|
||||
});
|
||||
});
|
|
@ -1,15 +1,47 @@
|
|||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import * as types from '../actions/actionsTypes';
|
||||
import { TActionsLogin } from '../actions/login';
|
||||
import { IUser } from '../definitions';
|
||||
|
||||
const initialState = {
|
||||
export interface IUserLogin {
|
||||
id: string;
|
||||
token: string;
|
||||
username: string;
|
||||
name: string;
|
||||
language?: string;
|
||||
status: UserStatus;
|
||||
statusText: string;
|
||||
roles: string[];
|
||||
avatarETag?: string;
|
||||
isFromWebView: boolean;
|
||||
showMessageInMainThread: boolean;
|
||||
enableMessageParserEarlyAdoption: boolean;
|
||||
emails: Record<string, any>[];
|
||||
customFields: Record<string, string>;
|
||||
settings?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface ILogin {
|
||||
user: Partial<IUser>;
|
||||
isLocalAuthenticated: boolean;
|
||||
isAuthenticated: boolean;
|
||||
isFetching: boolean;
|
||||
error: Record<string, any>;
|
||||
services: Record<string, any>;
|
||||
failure: boolean;
|
||||
}
|
||||
|
||||
export const initialState: ILogin = {
|
||||
isLocalAuthenticated: true,
|
||||
isAuthenticated: false,
|
||||
isFetching: false,
|
||||
user: {},
|
||||
error: {},
|
||||
services: {}
|
||||
services: {},
|
||||
failure: false
|
||||
};
|
||||
|
||||
export default function login(state = initialState, action) {
|
||||
export default function login(state = initialState, action: TActionsLogin): ILogin {
|
||||
switch (action.type) {
|
||||
case types.APP.INIT:
|
||||
return initialState;
|
||||
|
@ -60,13 +92,14 @@ export default function login(state = initialState, action) {
|
|||
...state,
|
||||
user: {
|
||||
...state.user,
|
||||
settings: {
|
||||
...state.user.settings,
|
||||
preferences: {
|
||||
...state.user.settings.preferences,
|
||||
...action.preference
|
||||
}
|
||||
}
|
||||
settings: state.user?.settings
|
||||
? {
|
||||
...state.user?.settings,
|
||||
preferences: state.user?.settings?.preferences
|
||||
? { ...state.user.settings.preferences, ...action.preference }
|
||||
: { ...action.preference }
|
||||
}
|
||||
: { profile: {}, preferences: {} }
|
||||
}
|
||||
};
|
||||
case types.LOGIN.SET_LOCAL_AUTHENTICATED:
|
|
@ -1,7 +1,7 @@
|
|||
import { createSelector } from 'reselect';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
import { IApplicationState } from '../definitions';
|
||||
import { IApplicationState, IUser } from '../definitions';
|
||||
|
||||
interface IServices {
|
||||
facebook: { clientId: string };
|
||||
|
@ -13,7 +13,7 @@ interface IServices {
|
|||
wordpress: { clientId: string; serverURL: string };
|
||||
}
|
||||
|
||||
const getUser = (state: IApplicationState) => {
|
||||
const getUser = (state: IApplicationState): Partial<IUser> => {
|
||||
if (!isEmpty(state.share?.user)) {
|
||||
return state.share.user;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ const getLoginServices = (state: IApplicationState) => (state.login.services as
|
|||
const getShowFormLoginSetting = (state: IApplicationState) => (state.settings.Accounts_ShowFormLogin as boolean) || false;
|
||||
const getIframeEnabledSetting = (state: IApplicationState) => (state.settings.Accounts_iframe_enabled as boolean) || false;
|
||||
|
||||
export const getUserSelector = createSelector([getUser], user => user);
|
||||
// TODO: we need to change 42 files to fix a correct type, i believe is better to do this later
|
||||
export const getUserSelector = createSelector([getUser], user => user) as any;
|
||||
|
||||
export const getShowLoginButton = createSelector(
|
||||
[getLoginServices, getShowFormLoginSetting, getIframeEnabledSetting],
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
import { dequal } from 'dequal';
|
||||
import React from 'react';
|
||||
import { Alert, Keyboard, StyleSheet, Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { dequal } from 'dequal';
|
||||
import { StackNavigationProp } from '@react-navigation/stack';
|
||||
import { RouteProp } from '@react-navigation/core';
|
||||
|
||||
import Button from '../containers/Button';
|
||||
import I18n from '../i18n';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { loginRequest } from '../actions/login';
|
||||
import { themes } from '../constants/colors';
|
||||
import { withTheme } from '../theme';
|
||||
import Button from '../containers/Button';
|
||||
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import LoginServices from '../containers/LoginServices';
|
||||
import sharedStyles from './Styles';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import { IApplicationState, IBaseScreen } from '../definitions';
|
||||
import I18n from '../i18n';
|
||||
import { OutsideParamList } from '../stacks/types';
|
||||
import { withTheme } from '../theme';
|
||||
import sharedStyles from './Styles';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
registerDisabled: {
|
||||
|
@ -48,9 +47,7 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
interface ILoginViewProps {
|
||||
navigation: StackNavigationProp<OutsideParamList, 'LoginView'>;
|
||||
route: RouteProp<OutsideParamList, 'LoginView'>;
|
||||
interface ILoginViewProps extends IBaseScreen<OutsideParamList, 'LoginView'> {
|
||||
Site_Name: string;
|
||||
Accounts_RegistrationForm: string;
|
||||
Accounts_RegistrationForm_LinkReplacementText: string;
|
||||
|
@ -63,7 +60,6 @@ interface ILoginViewProps {
|
|||
error: string;
|
||||
};
|
||||
failure: boolean;
|
||||
theme: string;
|
||||
loginRequest: Function;
|
||||
inviteLinkToken: string;
|
||||
}
|
||||
|
@ -132,9 +128,9 @@ class LoginView extends React.Component<ILoginViewProps, any> {
|
|||
}
|
||||
|
||||
const { user, password } = this.state;
|
||||
const { loginRequest } = this.props;
|
||||
const { dispatch } = this.props;
|
||||
Keyboard.dismiss();
|
||||
loginRequest({ user, password });
|
||||
dispatch(loginRequest({ user, password }));
|
||||
};
|
||||
|
||||
renderUserForm = () => {
|
||||
|
@ -243,23 +239,19 @@ class LoginView extends React.Component<ILoginViewProps, any> {
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
server: state.server.server,
|
||||
Site_Name: state.settings.Site_Name,
|
||||
Accounts_ShowFormLogin: state.settings.Accounts_ShowFormLogin,
|
||||
Accounts_RegistrationForm: state.settings.Accounts_RegistrationForm,
|
||||
Accounts_RegistrationForm_LinkReplacementText: state.settings.Accounts_RegistrationForm_LinkReplacementText,
|
||||
Site_Name: state.settings.Site_Name as string,
|
||||
Accounts_ShowFormLogin: state.settings.Accounts_ShowFormLogin as boolean,
|
||||
Accounts_RegistrationForm: state.settings.Accounts_RegistrationForm as string,
|
||||
Accounts_RegistrationForm_LinkReplacementText: state.settings.Accounts_RegistrationForm_LinkReplacementText as string,
|
||||
isFetching: state.login.isFetching,
|
||||
failure: state.login.failure,
|
||||
error: state.login.error && state.login.error.data,
|
||||
Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder,
|
||||
Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder,
|
||||
Accounts_PasswordReset: state.settings.Accounts_PasswordReset,
|
||||
Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder as string,
|
||||
Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder as string,
|
||||
Accounts_PasswordReset: state.settings.Accounts_PasswordReset as boolean,
|
||||
inviteLinkToken: state.inviteLinks.token
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: any) => ({
|
||||
loginRequest: (params: any) => dispatch(loginRequestAction(params))
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(LoginView));
|
||||
export default connect(mapStateToProps)(withTheme(LoginView));
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
import React from 'react';
|
||||
import { Keyboard, StyleSheet, Text, View } from 'react-native';
|
||||
import { StackNavigationProp } from '@react-navigation/stack';
|
||||
import { RouteProp } from '@react-navigation/core';
|
||||
import { connect } from 'react-redux';
|
||||
import RNPickerSelect from 'react-native-picker-select';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { OutsideParamList } from '../stacks/types';
|
||||
import log, { events, logEvent } from '../utils/log';
|
||||
import Button from '../containers/Button';
|
||||
import I18n from '../i18n';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { loginRequest } from '../actions/login';
|
||||
import { themes } from '../constants/colors';
|
||||
import { withTheme } from '../theme';
|
||||
import Button from '../containers/Button';
|
||||
import FormContainer, { FormContainerInner } from '../containers/FormContainer';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import isValidEmail from '../utils/isValidEmail';
|
||||
import { showErrorAlert } from '../utils/info';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||
import openLink from '../utils/openLink';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import LoginServices from '../containers/LoginServices';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import { IApplicationState, IBaseScreen } from '../definitions';
|
||||
import I18n from '../i18n';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import { getShowLoginButton } from '../selectors/login';
|
||||
import { OutsideParamList } from '../stacks/types';
|
||||
import { withTheme } from '../theme';
|
||||
import { showErrorAlert } from '../utils/info';
|
||||
import isValidEmail from '../utils/isValidEmail';
|
||||
import log, { events, logEvent } from '../utils/log';
|
||||
import openLink from '../utils/openLink';
|
||||
import sharedStyles from './Styles';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -51,9 +50,7 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
interface IProps {
|
||||
navigation: StackNavigationProp<OutsideParamList, 'RegisterView'>;
|
||||
route: RouteProp<OutsideParamList, 'RegisterView'>;
|
||||
interface IProps extends IBaseScreen<OutsideParamList, 'RegisterView'> {
|
||||
server: string;
|
||||
Site_Name: string;
|
||||
Gitlab_URL: string;
|
||||
|
@ -63,8 +60,6 @@ interface IProps {
|
|||
Accounts_EmailVerification: boolean;
|
||||
Accounts_ManuallyApproveNewUsers: boolean;
|
||||
showLoginButton: boolean;
|
||||
loginRequest: Function;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
class RegisterView extends React.Component<IProps, any> {
|
||||
|
@ -130,7 +125,7 @@ class RegisterView extends React.Component<IProps, any> {
|
|||
Keyboard.dismiss();
|
||||
|
||||
const { name, email, password, username, customFields } = this.state;
|
||||
const { loginRequest, Accounts_EmailVerification, navigation, Accounts_ManuallyApproveNewUsers } = this.props;
|
||||
const { dispatch, Accounts_EmailVerification, navigation, Accounts_ManuallyApproveNewUsers } = this.props;
|
||||
|
||||
try {
|
||||
await RocketChat.register({
|
||||
|
@ -148,11 +143,11 @@ class RegisterView extends React.Component<IProps, any> {
|
|||
await navigation.goBack();
|
||||
showErrorAlert(I18n.t('Wait_activation_warning'), I18n.t('Registration_Succeeded'));
|
||||
} else {
|
||||
await loginRequest({ user: email, password });
|
||||
dispatch(loginRequest({ user: email, password }));
|
||||
}
|
||||
} catch (e: any) {
|
||||
if (e.data?.errorType === 'username-invalid') {
|
||||
return loginRequest({ user: email, password });
|
||||
return dispatch(loginRequest({ user: email, password }));
|
||||
}
|
||||
if (e.data?.error) {
|
||||
logEvent(events.REGISTER_DEFAULT_SIGN_UP_F);
|
||||
|
@ -349,20 +344,16 @@ class RegisterView extends React.Component<IProps, any> {
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
server: state.server.server,
|
||||
Site_Name: state.settings.Site_Name,
|
||||
Gitlab_URL: state.settings.API_Gitlab_URL,
|
||||
CAS_enabled: state.settings.CAS_enabled,
|
||||
CAS_login_url: state.settings.CAS_login_url,
|
||||
Accounts_CustomFields: state.settings.Accounts_CustomFields,
|
||||
Accounts_EmailVerification: state.settings.Accounts_EmailVerification,
|
||||
Accounts_ManuallyApproveNewUsers: state.settings.Accounts_ManuallyApproveNewUsers,
|
||||
Site_Name: state.settings.Site_Name as string,
|
||||
Gitlab_URL: state.settings.API_Gitlab_URL as string,
|
||||
CAS_enabled: state.settings.CAS_enabled as boolean,
|
||||
CAS_login_url: state.settings.CAS_login_url as string,
|
||||
Accounts_CustomFields: state.settings.Accounts_CustomFields as string,
|
||||
Accounts_EmailVerification: state.settings.Accounts_EmailVerification as boolean,
|
||||
Accounts_ManuallyApproveNewUsers: state.settings.Accounts_ManuallyApproveNewUsers as boolean,
|
||||
showLoginButton: getShowLoginButton(state)
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: any) => ({
|
||||
loginRequest: (params: any) => dispatch(loginRequestAction(params))
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(RegisterView));
|
||||
export default connect(mapStateToProps)(withTheme(RegisterView));
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
import React from 'react';
|
||||
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
|
||||
import { Dispatch } from 'redux';
|
||||
import { ScrollView, StyleSheet, Text } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import Orientation from 'react-native-orientation-locker';
|
||||
import { RouteProp } from '@react-navigation/native';
|
||||
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import { ScrollView, StyleSheet, Text } from 'react-native';
|
||||
import Orientation from 'react-native-orientation-locker';
|
||||
import { connect } from 'react-redux';
|
||||
import { Dispatch } from 'redux';
|
||||
|
||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import { loginRequest } from '../actions/login';
|
||||
import { themes } from '../constants/colors';
|
||||
import Button from '../containers/Button';
|
||||
import KeyboardView from '../presentation/KeyboardView';
|
||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import { IApplicationState } from '../definitions';
|
||||
import I18n from '../i18n';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { withTheme } from '../theme';
|
||||
import { themes } from '../constants/colors';
|
||||
import { isTablet } from '../utils/deviceInfo';
|
||||
import KeyboardView from '../presentation/KeyboardView';
|
||||
import { getUserSelector } from '../selectors/login';
|
||||
import { withTheme } from '../theme';
|
||||
import { isTablet } from '../utils/deviceInfo';
|
||||
import { showErrorAlert } from '../utils/info';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import sharedStyles from './Styles';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -39,9 +40,9 @@ interface ISetUsernameViewProps {
|
|||
route: RouteProp<{ SetUsernameView: { title: string } }, 'SetUsernameView'>;
|
||||
server: string;
|
||||
userId: string;
|
||||
loginRequest: ({ resume }: { resume: string }) => void;
|
||||
token: string;
|
||||
theme: string;
|
||||
dispatch: Dispatch;
|
||||
}
|
||||
|
||||
class SetUsernameView extends React.Component<ISetUsernameViewProps, ISetUsernameViewState> {
|
||||
|
@ -86,7 +87,7 @@ class SetUsernameView extends React.Component<ISetUsernameViewProps, ISetUsernam
|
|||
|
||||
submit = async () => {
|
||||
const { username } = this.state;
|
||||
const { loginRequest, token } = this.props;
|
||||
const { dispatch, token } = this.props;
|
||||
|
||||
if (!username.trim()) {
|
||||
return;
|
||||
|
@ -95,7 +96,7 @@ class SetUsernameView extends React.Component<ISetUsernameViewProps, ISetUsernam
|
|||
this.setState({ saving: true });
|
||||
try {
|
||||
await RocketChat.saveUserProfile({ username });
|
||||
await loginRequest({ resume: token });
|
||||
dispatch(loginRequest({ resume: token }));
|
||||
} catch (e: any) {
|
||||
showErrorAlert(e.message, I18n.t('Oops'));
|
||||
}
|
||||
|
@ -144,13 +145,9 @@ class SetUsernameView extends React.Component<ISetUsernameViewProps, ISetUsernam
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
server: state.server.server,
|
||||
token: getUserSelector(state).token
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: Dispatch) => ({
|
||||
loginRequest: (params: { resume: string }) => dispatch(loginRequestAction(params))
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(SetUsernameView));
|
||||
export default connect(mapStateToProps)(withTheme(SetUsernameView));
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
import React from 'react';
|
||||
import { StackNavigationProp } from '@react-navigation/stack';
|
||||
import { FlatList, StyleSheet } from 'react-native';
|
||||
import { Dispatch } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import I18n from '../i18n';
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import { setUser } from '../actions/login';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import * as List from '../containers/List';
|
||||
import Loading from '../containers/Loading';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import Status from '../containers/Status/Status';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import { LISTENER } from '../containers/Toast';
|
||||
import { IApplicationState, IBaseScreen } from '../definitions';
|
||||
import I18n from '../i18n';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import { getUserSelector } from '../selectors/login';
|
||||
import { withTheme } from '../theme';
|
||||
import EventEmitter from '../utils/events';
|
||||
import { showErrorAlert } from '../utils/info';
|
||||
import Loading from '../containers/Loading';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import log, { events, logEvent } from '../utils/log';
|
||||
import { LISTENER } from '../containers/Toast';
|
||||
import { withTheme } from '../theme';
|
||||
import { getUserSelector } from '../selectors/login';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import { setUser as setUserAction } from '../actions/login';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
|
||||
const STATUS = [
|
||||
{
|
||||
|
@ -65,12 +65,9 @@ interface IStatusViewState {
|
|||
loading: boolean;
|
||||
}
|
||||
|
||||
interface IStatusViewProps {
|
||||
navigation: StackNavigationProp<any, 'StatusView'>;
|
||||
interface IStatusViewProps extends IBaseScreen<any, 'StatusView'> {
|
||||
user: IUser;
|
||||
theme: string;
|
||||
isMasterDetail: boolean;
|
||||
setUser: (user: IUser) => void;
|
||||
Accounts_AllowInvisibleStatusOption: boolean;
|
||||
}
|
||||
|
||||
|
@ -111,7 +108,7 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
};
|
||||
|
||||
setCustomStatus = async (statusText: string) => {
|
||||
const { user, setUser } = this.props;
|
||||
const { user, dispatch } = this.props;
|
||||
|
||||
this.setState({ loading: true });
|
||||
|
||||
|
@ -119,7 +116,7 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
const result = await RocketChat.setUserStatus(user.status, statusText);
|
||||
if (result.success) {
|
||||
logEvent(events.STATUS_CUSTOM);
|
||||
setUser({ statusText });
|
||||
dispatch(setUser({ statusText }));
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Status_saved_successfully') });
|
||||
} else {
|
||||
logEvent(events.STATUS_CUSTOM_F);
|
||||
|
@ -156,7 +153,7 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
|
||||
renderItem = ({ item }: { item: { id: string; name: string } }) => {
|
||||
const { statusText } = this.state;
|
||||
const { user, setUser } = this.props;
|
||||
const { user, dispatch } = this.props;
|
||||
const { id, name } = item;
|
||||
return (
|
||||
<List.Item
|
||||
|
@ -168,7 +165,7 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
try {
|
||||
const result = await RocketChat.setUserStatus(item.id, statusText);
|
||||
if (result.success) {
|
||||
setUser({ status: item.id });
|
||||
dispatch(setUser({ status: item.id as UserStatus }));
|
||||
}
|
||||
} catch (e: any) {
|
||||
showErrorAlert(I18n.t(e.data.errorType));
|
||||
|
@ -205,14 +202,10 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
user: getUserSelector(state),
|
||||
isMasterDetail: state.app.isMasterDetail,
|
||||
Accounts_AllowInvisibleStatusOption: state.settings.Accounts_AllowInvisibleStatusOption ?? true
|
||||
Accounts_AllowInvisibleStatusOption: (state.settings.Accounts_AllowInvisibleStatusOption as boolean) ?? true
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: Dispatch) => ({
|
||||
setUser: (user: IUser) => dispatch(setUserAction(user))
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(StatusView));
|
||||
export default connect(mapStateToProps)(withTheme(StatusView));
|
||||
|
|
Loading…
Reference in New Issue