feat: add bio and nickname to profile view (#5060)
* feat: add bio and nickname to profile view * add the text input in profileview * fix the bio layout and add to translation * fix e2e tests * add max length to nickname and bio * refactor a bit the inputRef * fix the text align vertical of multiline
This commit is contained in:
parent
5c5ff2d51f
commit
a203f67a4a
|
@ -22,6 +22,8 @@ export interface ILoggedUser {
|
||||||
isFromWebView?: boolean;
|
isFromWebView?: boolean;
|
||||||
enableMessageParserEarlyAdoption: boolean;
|
enableMessageParserEarlyAdoption: boolean;
|
||||||
alsoSendThreadToChannel: 'default' | 'always' | 'never';
|
alsoSendThreadToChannel: 'default' | 'always' | 'never';
|
||||||
|
bio?: string;
|
||||||
|
nickname?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILoggedUserResultFromServer
|
export interface ILoggedUserResultFromServer
|
||||||
|
|
|
@ -7,6 +7,8 @@ export interface IProfileParams {
|
||||||
email: string | null;
|
email: string | null;
|
||||||
newPassword: string;
|
newPassword: string;
|
||||||
currentPassword: string;
|
currentPassword: string;
|
||||||
|
bio?: string;
|
||||||
|
nickname?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAvatarButton {
|
export interface IAvatarButton {
|
||||||
|
|
|
@ -726,6 +726,8 @@
|
||||||
"Presence_Cap_Warning_Description": "Active connections have reached the limit for the workspace, thus the service that handles user status is disabled. It can be re-enabled manually in workspace settings.",
|
"Presence_Cap_Warning_Description": "Active connections have reached the limit for the workspace, thus the service that handles user status is disabled. It can be re-enabled manually in workspace settings.",
|
||||||
"Learn_more": "Learn more",
|
"Learn_more": "Learn more",
|
||||||
"and_N_more": "and {{count}} more",
|
"and_N_more": "and {{count}} more",
|
||||||
|
"Nickname": "Nickname",
|
||||||
|
"Bio":"Bio",
|
||||||
"decline": "Decline",
|
"decline": "Decline",
|
||||||
"accept": "Accept",
|
"accept": "Accept",
|
||||||
"Incoming_call_from": "Incoming call from",
|
"Incoming_call_from": "Incoming call from",
|
||||||
|
|
|
@ -711,6 +711,8 @@
|
||||||
"Discard_changes_description": "Todas as alterações serão perdidas, se você sair sem salvar.",
|
"Discard_changes_description": "Todas as alterações serão perdidas, se você sair sem salvar.",
|
||||||
"Presence_Cap_Warning_Title": "Status do usuário desabilitado temporariamente",
|
"Presence_Cap_Warning_Title": "Status do usuário desabilitado temporariamente",
|
||||||
"Presence_Cap_Warning_Description": "O limite de conexões ativas para a workspace foi atingido, por isso o serviço responsável pela presença dos usuários está temporariamente desabilitado. Ele pode ser reabilitado manualmente nas configurações da workspace.",
|
"Presence_Cap_Warning_Description": "O limite de conexões ativas para a workspace foi atingido, por isso o serviço responsável pela presença dos usuários está temporariamente desabilitado. Ele pode ser reabilitado manualmente nas configurações da workspace.",
|
||||||
|
"Nickname": "Apelido",
|
||||||
|
"Bio": "Biografia",
|
||||||
"decline": "Recusar",
|
"decline": "Recusar",
|
||||||
"accept": "Aceitar",
|
"accept": "Aceitar",
|
||||||
"Incoming_call_from": "Chamada recebida de",
|
"Incoming_call_from": "Chamada recebida de",
|
||||||
|
|
|
@ -29,4 +29,8 @@ export default class User extends Model {
|
||||||
@field('is_from_webview') isFromWebView;
|
@field('is_from_webview') isFromWebView;
|
||||||
|
|
||||||
@field('enable_message_parser_early_adoption') enableMessageParserEarlyAdoption;
|
@field('enable_message_parser_early_adoption') enableMessageParserEarlyAdoption;
|
||||||
|
|
||||||
|
@field('nickname') nickname;
|
||||||
|
|
||||||
|
@field('bio') bio;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,18 @@ export default schemaMigrations({
|
||||||
columns: [{ name: 'enable_message_parser_early_adoption', type: 'boolean', isOptional: true }]
|
columns: [{ name: 'enable_message_parser_early_adoption', type: 'boolean', isOptional: true }]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
toVersion: 13,
|
||||||
|
steps: [
|
||||||
|
addColumns({
|
||||||
|
table: 'users',
|
||||||
|
columns: [
|
||||||
|
{ name: 'nickname', type: 'string', isOptional: true },
|
||||||
|
{ name: 'bio', type: 'string', isOptional: true }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
export default appSchema({
|
export default appSchema({
|
||||||
version: 12,
|
version: 13,
|
||||||
tables: [
|
tables: [
|
||||||
tableSchema({
|
tableSchema({
|
||||||
name: 'users',
|
name: 'users',
|
||||||
|
@ -17,7 +17,9 @@ export default appSchema({
|
||||||
{ name: 'show_message_in_main_thread', type: 'boolean', isOptional: true },
|
{ name: 'show_message_in_main_thread', type: 'boolean', isOptional: true },
|
||||||
{ name: 'avatar_etag', type: 'string', isOptional: true },
|
{ name: 'avatar_etag', type: 'string', isOptional: true },
|
||||||
{ name: 'is_from_webview', type: 'boolean', isOptional: true },
|
{ name: 'is_from_webview', type: 'boolean', isOptional: true },
|
||||||
{ name: 'enable_message_parser_early_adoption', type: 'boolean', isOptional: true }
|
{ name: 'enable_message_parser_early_adoption', type: 'boolean', isOptional: true },
|
||||||
|
{ name: 'nickname', type: 'string', isOptional: true },
|
||||||
|
{ name: 'bio', type: 'string', isOptional: true }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
tableSchema({
|
tableSchema({
|
||||||
|
|
|
@ -309,6 +309,12 @@ export default function subscribeRooms() {
|
||||||
if (unset?.avatarETag) {
|
if (unset?.avatarETag) {
|
||||||
store.dispatch(setUser({ avatarETag: '' }));
|
store.dispatch(setUser({ avatarETag: '' }));
|
||||||
}
|
}
|
||||||
|
if (diff?.bio) {
|
||||||
|
store.dispatch(setUser({ bio: diff.bio }));
|
||||||
|
}
|
||||||
|
if (diff?.nickname) {
|
||||||
|
store.dispatch(setUser({ nickname: diff.nickname }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (/subscriptions/.test(ev)) {
|
if (/subscriptions/.test(ev)) {
|
||||||
if (type === 'removed') {
|
if (type === 'removed') {
|
||||||
|
|
|
@ -304,7 +304,9 @@ async function login(credentials: ICredentials, isFromWebView = false): Promise<
|
||||||
isFromWebView,
|
isFromWebView,
|
||||||
showMessageInMainThread,
|
showMessageInMainThread,
|
||||||
enableMessageParserEarlyAdoption,
|
enableMessageParserEarlyAdoption,
|
||||||
alsoSendThreadToChannel: result.me.settings?.preferences?.alsoSendThreadToChannel
|
alsoSendThreadToChannel: result.me.settings?.preferences?.alsoSendThreadToChannel,
|
||||||
|
bio: result.me.bio,
|
||||||
|
nickname: result.me.nickname
|
||||||
};
|
};
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,9 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
roles: user.roles,
|
roles: user.roles,
|
||||||
isFromWebView: user.isFromWebView,
|
isFromWebView: user.isFromWebView,
|
||||||
showMessageInMainThread: user.showMessageInMainThread,
|
showMessageInMainThread: user.showMessageInMainThread,
|
||||||
avatarETag: user.avatarETag
|
avatarETag: user.avatarETag,
|
||||||
|
bio: user.bio,
|
||||||
|
nickname: user.nickname
|
||||||
};
|
};
|
||||||
yield serversDB.action(async () => {
|
yield serversDB.action(async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -94,7 +94,9 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
|
||||||
status: userRecord.status,
|
status: userRecord.status,
|
||||||
statusText: userRecord.statusText,
|
statusText: userRecord.statusText,
|
||||||
roles: userRecord.roles,
|
roles: userRecord.roles,
|
||||||
avatarETag: userRecord.avatarETag
|
avatarETag: userRecord.avatarETag,
|
||||||
|
bio: userRecord.bio,
|
||||||
|
nickname: userRecord.nickname
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
// search credentials on shared credentials (Experimental/Official)
|
// search credentials on shared credentials (Experimental/Official)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Touch from '../../containers/Touch';
|
||||||
import KeyboardView from '../../containers/KeyboardView';
|
import KeyboardView from '../../containers/KeyboardView';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
||||||
import { showErrorAlert, showConfirmationAlert } from '../../lib/methods/helpers';
|
import { showErrorAlert, showConfirmationAlert, compareServerVersion } from '../../lib/methods/helpers';
|
||||||
import { LISTENER } from '../../containers/Toast';
|
import { LISTENER } from '../../containers/Toast';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
import { FormTextInput } from '../../containers/TextInput';
|
import { FormTextInput } from '../../containers/TextInput';
|
||||||
|
@ -36,6 +36,10 @@ import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSh
|
||||||
import { DeleteAccountActionSheetContent } from './components/DeleteAccountActionSheetContent';
|
import { DeleteAccountActionSheetContent } from './components/DeleteAccountActionSheetContent';
|
||||||
import ActionSheetContentWithInputAndSubmit from '../../containers/ActionSheet/ActionSheetContentWithInputAndSubmit';
|
import ActionSheetContentWithInputAndSubmit from '../../containers/ActionSheet/ActionSheetContentWithInputAndSubmit';
|
||||||
|
|
||||||
|
// https://github.com/RocketChat/Rocket.Chat/blob/174c28d40b3d5a52023ee2dca2e81dd77ff33fa5/apps/meteor/app/lib/server/functions/saveUser.js#L24-L25
|
||||||
|
const MAX_BIO_LENGTH = 260;
|
||||||
|
const MAX_NICKNAME_LENGTH = 120;
|
||||||
|
|
||||||
interface IProfileViewProps extends IActionSheetProvider, IBaseScreen<ProfileStackParamList, 'ProfileView'> {
|
interface IProfileViewProps extends IActionSheetProvider, IBaseScreen<ProfileStackParamList, 'ProfileView'> {
|
||||||
user: IUser;
|
user: IUser;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
|
@ -48,6 +52,7 @@ interface IProfileViewProps extends IActionSheetProvider, IBaseScreen<ProfileSta
|
||||||
theme: TSupportedThemes;
|
theme: TSupportedThemes;
|
||||||
Accounts_AllowDeleteOwnAccount: boolean;
|
Accounts_AllowDeleteOwnAccount: boolean;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
|
serverVersion: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IProfileViewState {
|
interface IProfileViewState {
|
||||||
|
@ -55,6 +60,8 @@ interface IProfileViewState {
|
||||||
name: string;
|
name: string;
|
||||||
username: string;
|
username: string;
|
||||||
email: string | null;
|
email: string | null;
|
||||||
|
bio?: string;
|
||||||
|
nickname?: string;
|
||||||
newPassword: string | null;
|
newPassword: string | null;
|
||||||
currentPassword: string | null;
|
currentPassword: string | null;
|
||||||
customFields: {
|
customFields: {
|
||||||
|
@ -69,9 +76,11 @@ interface IProfileViewState {
|
||||||
class ProfileView extends React.Component<IProfileViewProps, IProfileViewState> {
|
class ProfileView extends React.Component<IProfileViewProps, IProfileViewState> {
|
||||||
private name?: TextInput | null;
|
private name?: TextInput | null;
|
||||||
private username?: TextInput | null;
|
private username?: TextInput | null;
|
||||||
private email?: TextInput;
|
private email?: TextInput | null;
|
||||||
private avatarUrl?: TextInput;
|
private avatarUrl?: TextInput | null;
|
||||||
private newPassword?: TextInput;
|
private newPassword?: TextInput | null;
|
||||||
|
private nickname?: TextInput | null;
|
||||||
|
private bio?: TextInput | null;
|
||||||
|
|
||||||
setHeader = () => {
|
setHeader = () => {
|
||||||
const { navigation, isMasterDetail } = this.props;
|
const { navigation, isMasterDetail } = this.props;
|
||||||
|
@ -98,6 +107,8 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
name: '',
|
name: '',
|
||||||
username: '',
|
username: '',
|
||||||
email: '',
|
email: '',
|
||||||
|
bio: '',
|
||||||
|
nickname: '',
|
||||||
newPassword: '',
|
newPassword: '',
|
||||||
currentPassword: '',
|
currentPassword: '',
|
||||||
customFields: {},
|
customFields: {},
|
||||||
|
@ -123,7 +134,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
|
|
||||||
init = (user?: IUser) => {
|
init = (user?: IUser) => {
|
||||||
const { user: userProps } = this.props;
|
const { user: userProps } = this.props;
|
||||||
const { name, username, emails, customFields } = user || userProps;
|
const { name, username, emails, customFields, bio, nickname } = user || userProps;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
name: name as string,
|
name: name as string,
|
||||||
|
@ -131,12 +142,14 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
email: emails ? emails[0].address : null,
|
email: emails ? emails[0].address : null,
|
||||||
newPassword: null,
|
newPassword: null,
|
||||||
currentPassword: null,
|
currentPassword: null,
|
||||||
customFields: customFields || {}
|
customFields: customFields || {},
|
||||||
|
bio,
|
||||||
|
nickname
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
formIsChanged = () => {
|
formIsChanged = () => {
|
||||||
const { name, username, email, newPassword, customFields } = this.state;
|
const { name, username, email, newPassword, customFields, bio, nickname } = this.state;
|
||||||
const { user } = this.props;
|
const { user } = this.props;
|
||||||
let customFieldsChanged = false;
|
let customFieldsChanged = false;
|
||||||
|
|
||||||
|
@ -152,6 +165,8 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
return !(
|
return !(
|
||||||
user.name === name &&
|
user.name === name &&
|
||||||
user.username === username &&
|
user.username === username &&
|
||||||
|
user.bio === bio &&
|
||||||
|
user.nickname === nickname &&
|
||||||
!newPassword &&
|
!newPassword &&
|
||||||
user.emails &&
|
user.emails &&
|
||||||
user.emails[0].address === email &&
|
user.emails[0].address === email &&
|
||||||
|
@ -168,7 +183,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
|
|
||||||
this.setState({ saving: true });
|
this.setState({ saving: true });
|
||||||
|
|
||||||
const { name, username, email, newPassword, currentPassword, customFields, twoFactorCode } = this.state;
|
const { name, username, email, newPassword, currentPassword, customFields, twoFactorCode, bio, nickname } = this.state;
|
||||||
const { user, dispatch } = this.props;
|
const { user, dispatch } = this.props;
|
||||||
const params = {} as IProfileParams;
|
const params = {} as IProfileParams;
|
||||||
|
|
||||||
|
@ -187,6 +202,14 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
params.email = email;
|
params.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.bio !== bio) {
|
||||||
|
params.bio = bio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.nickname !== nickname) {
|
||||||
|
params.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
// newPassword
|
// newPassword
|
||||||
if (newPassword) {
|
if (newPassword) {
|
||||||
params.newPassword = newPassword;
|
params.newPassword = newPassword;
|
||||||
|
@ -400,7 +423,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { name, username, email, newPassword, customFields, saving } = this.state;
|
const { name, username, email, newPassword, customFields, saving, nickname, bio } = this.state;
|
||||||
const {
|
const {
|
||||||
user,
|
user,
|
||||||
theme,
|
theme,
|
||||||
|
@ -410,7 +433,8 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
Accounts_AllowUserAvatarChange,
|
Accounts_AllowUserAvatarChange,
|
||||||
Accounts_AllowUsernameChange,
|
Accounts_AllowUsernameChange,
|
||||||
Accounts_CustomFields,
|
Accounts_CustomFields,
|
||||||
Accounts_AllowDeleteOwnAccount
|
Accounts_AllowDeleteOwnAccount,
|
||||||
|
serverVersion
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -431,9 +455,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
<FormTextInput
|
<FormTextInput
|
||||||
editable={Accounts_AllowRealNameChange}
|
editable={Accounts_AllowRealNameChange}
|
||||||
inputStyle={[!Accounts_AllowRealNameChange && styles.disabled]}
|
inputStyle={[!Accounts_AllowRealNameChange && styles.disabled]}
|
||||||
inputRef={e => {
|
inputRef={e => (this.name = e)}
|
||||||
this.name = e;
|
|
||||||
}}
|
|
||||||
label={I18n.t('Name')}
|
label={I18n.t('Name')}
|
||||||
placeholder={I18n.t('Name')}
|
placeholder={I18n.t('Name')}
|
||||||
value={name}
|
value={name}
|
||||||
|
@ -446,9 +468,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
<FormTextInput
|
<FormTextInput
|
||||||
editable={Accounts_AllowUsernameChange}
|
editable={Accounts_AllowUsernameChange}
|
||||||
inputStyle={[!Accounts_AllowUsernameChange && styles.disabled]}
|
inputStyle={[!Accounts_AllowUsernameChange && styles.disabled]}
|
||||||
inputRef={e => {
|
inputRef={e => (this.username = e)}
|
||||||
this.username = e;
|
|
||||||
}}
|
|
||||||
label={I18n.t('Username')}
|
label={I18n.t('Username')}
|
||||||
placeholder={I18n.t('Username')}
|
placeholder={I18n.t('Username')}
|
||||||
value={username}
|
value={username}
|
||||||
|
@ -461,28 +481,48 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
<FormTextInput
|
<FormTextInput
|
||||||
editable={Accounts_AllowEmailChange}
|
editable={Accounts_AllowEmailChange}
|
||||||
inputStyle={[!Accounts_AllowEmailChange && styles.disabled]}
|
inputStyle={[!Accounts_AllowEmailChange && styles.disabled]}
|
||||||
inputRef={e => {
|
inputRef={e => (this.email = e)}
|
||||||
if (e) {
|
|
||||||
this.email = e;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
label={I18n.t('Email')}
|
label={I18n.t('Email')}
|
||||||
placeholder={I18n.t('Email')}
|
placeholder={I18n.t('Email')}
|
||||||
value={email || undefined}
|
value={email || undefined}
|
||||||
onChangeText={value => this.setState({ email: value })}
|
onChangeText={value => this.setState({ email: value })}
|
||||||
onSubmitEditing={() => {
|
onSubmitEditing={() => {
|
||||||
this.newPassword?.focus();
|
this.nickname?.focus();
|
||||||
}}
|
}}
|
||||||
testID='profile-view-email'
|
testID='profile-view-email'
|
||||||
/>
|
/>
|
||||||
|
{compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '3.5.0') ? (
|
||||||
|
<FormTextInput
|
||||||
|
inputRef={e => (this.nickname = e)}
|
||||||
|
label={I18n.t('Nickname')}
|
||||||
|
value={nickname}
|
||||||
|
onChangeText={value => this.setState({ nickname: value })}
|
||||||
|
onSubmitEditing={() => {
|
||||||
|
this.bio?.focus();
|
||||||
|
}}
|
||||||
|
testID='profile-view-nickname'
|
||||||
|
maxLength={MAX_NICKNAME_LENGTH}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
{compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '3.1.0') ? (
|
||||||
|
<FormTextInput
|
||||||
|
inputRef={e => (this.bio = e)}
|
||||||
|
label={I18n.t('Bio')}
|
||||||
|
inputStyle={styles.inputBio}
|
||||||
|
multiline
|
||||||
|
maxLength={MAX_BIO_LENGTH}
|
||||||
|
value={bio}
|
||||||
|
onChangeText={value => this.setState({ bio: value })}
|
||||||
|
onSubmitEditing={() => {
|
||||||
|
this.newPassword?.focus();
|
||||||
|
}}
|
||||||
|
testID='profile-view-bio'
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
<FormTextInput
|
<FormTextInput
|
||||||
editable={Accounts_AllowPasswordChange}
|
editable={Accounts_AllowPasswordChange}
|
||||||
inputStyle={[!Accounts_AllowPasswordChange && styles.disabled]}
|
inputStyle={[!Accounts_AllowPasswordChange && styles.disabled]}
|
||||||
inputRef={e => {
|
inputRef={e => (this.newPassword = e)}
|
||||||
if (e) {
|
|
||||||
this.newPassword = e;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
label={I18n.t('New_Password')}
|
label={I18n.t('New_Password')}
|
||||||
placeholder={I18n.t('New_Password')}
|
placeholder={I18n.t('New_Password')}
|
||||||
value={newPassword || undefined}
|
value={newPassword || undefined}
|
||||||
|
@ -539,6 +579,7 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
Accounts_AllowUsernameChange: state.settings.Accounts_AllowUsernameChange as boolean,
|
Accounts_AllowUsernameChange: state.settings.Accounts_AllowUsernameChange as boolean,
|
||||||
Accounts_CustomFields: state.settings.Accounts_CustomFields as string,
|
Accounts_CustomFields: state.settings.Accounts_CustomFields as string,
|
||||||
baseUrl: state.server.server,
|
baseUrl: state.server.server,
|
||||||
|
serverVersion: state.server.version,
|
||||||
Accounts_AllowDeleteOwnAccount: state.settings.Accounts_AllowDeleteOwnAccount as boolean
|
Accounts_AllowDeleteOwnAccount: state.settings.Accounts_AllowDeleteOwnAccount as boolean
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,9 @@ export default StyleSheet.create({
|
||||||
marginRight: 15,
|
marginRight: 15,
|
||||||
marginBottom: 15,
|
marginBottom: 15,
|
||||||
borderRadius: 4
|
borderRadius: 4
|
||||||
|
},
|
||||||
|
inputBio: {
|
||||||
|
height: 100,
|
||||||
|
textAlignVertical: 'top'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,6 +10,12 @@ async function waitForToast() {
|
||||||
await sleep(600);
|
await sleep(600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function dismissKeyboardAndScrollUp() {
|
||||||
|
await element(by.id('profile-view-list')).swipe('down');
|
||||||
|
await sleep(300);
|
||||||
|
await element(by.id('profile-view-list')).swipe('up');
|
||||||
|
}
|
||||||
|
|
||||||
describe('Profile screen', () => {
|
describe('Profile screen', () => {
|
||||||
let textMatcher: TTextMatcher;
|
let textMatcher: TTextMatcher;
|
||||||
let user: ITestUser;
|
let user: ITestUser;
|
||||||
|
@ -74,23 +80,27 @@ describe('Profile screen', () => {
|
||||||
it('should change name and username', async () => {
|
it('should change name and username', async () => {
|
||||||
await element(by.id('profile-view-name')).replaceText(`${user.username}new`);
|
await element(by.id('profile-view-name')).replaceText(`${user.username}new`);
|
||||||
await element(by.id('profile-view-username')).replaceText(`${user.username}new`);
|
await element(by.id('profile-view-username')).replaceText(`${user.username}new`);
|
||||||
// dismiss keyboard
|
await dismissKeyboardAndScrollUp();
|
||||||
await element(by.id('profile-view-list')).swipe('down');
|
await element(by.id('profile-view-submit')).tap();
|
||||||
|
await waitForToast();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change nickname and bio', async () => {
|
||||||
|
await element(by.id('profile-view-nickname')).replaceText(`nickname-${user.username}`);
|
||||||
|
await element(by.id('profile-view-bio')).replaceText(`bio-${user.username}`);
|
||||||
|
await dismissKeyboardAndScrollUp();
|
||||||
await element(by.id('profile-view-submit')).tap();
|
await element(by.id('profile-view-submit')).tap();
|
||||||
await waitForToast();
|
await waitForToast();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change email and password', async () => {
|
it('should change email and password', async () => {
|
||||||
await element(by.id('profile-view-list')).swipe('up');
|
await element(by.id('profile-view-list')).swipe('down');
|
||||||
await waitFor(element(by.id('profile-view-email')))
|
await waitFor(element(by.id('profile-view-email')))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(2000);
|
.withTimeout(2000);
|
||||||
await element(by.id('profile-view-email')).replaceText(`mobile+profileChangesNew${random()}@rocket.chat`);
|
await element(by.id('profile-view-email')).replaceText(`mobile+profileChangesNew${random()}@rocket.chat`);
|
||||||
// dismiss keyboard
|
await dismissKeyboardAndScrollUp();
|
||||||
await element(by.id('profile-view-list')).swipe('down');
|
|
||||||
await element(by.id('profile-view-new-password')).replaceText(`${user.password}new`);
|
await element(by.id('profile-view-new-password')).replaceText(`${user.password}new`);
|
||||||
// dismiss keyboard
|
|
||||||
await element(by.id('profile-view-list')).swipe('down');
|
|
||||||
await waitFor(element(by.id('profile-view-submit')))
|
await waitFor(element(by.id('profile-view-submit')))
|
||||||
.toExist()
|
.toExist()
|
||||||
.withTimeout(2000);
|
.withTimeout(2000);
|
||||||
|
|
Loading…
Reference in New Issue