vn-verdnaturachat/app/views/ProfileView/index.js

606 lines
17 KiB
JavaScript
Raw Normal View History

2018-06-05 01:17:02 +00:00
import React from 'react';
import PropTypes from 'prop-types';
import { View, ScrollView, Keyboard } from 'react-native';
import { connect } from 'react-redux';
2020-03-03 20:27:38 +00:00
import prompt from 'react-native-prompt-android';
import SHA256 from 'js-sha256';
import ImagePicker from 'react-native-image-crop-picker';
import RNPickerSelect from 'react-native-picker-select';
import { isEqual, omit } from 'lodash';
2018-06-05 01:17:02 +00:00
2019-12-04 16:39:53 +00:00
import Touch from '../../utils/touch';
import KeyboardView from '../../presentation/KeyboardView';
import sharedStyles from '../Styles';
import styles from './styles';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { showErrorAlert, showConfirmationAlert } from '../../utils/info';
2019-07-23 14:02:57 +00:00
import { LISTENER } from '../../containers/Toast';
import EventEmitter from '../../utils/events';
import RocketChat from '../../lib/rocketchat';
import RCTextInput from '../../containers/TextInput';
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
import log, { logEvent, events } from '../../utils/log';
import I18n from '../../i18n';
import Button from '../../containers/Button';
import Avatar from '../../containers/Avatar';
import { setUser as setUserAction } from '../../actions/login';
import { CustomIcon } from '../../lib/Icons';
[NEW] User notification preferences (#2403) * Button to preferences view Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Create screen to preferences and listItem to notifications Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Refactoring NotificationPreferencesView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * List notification preferences Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Adding translations to labels Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * SetUserPreferences api call Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Saving new user preference in API Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Fix lint Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Add in-app notification test Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Fix in app mentions preference Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Improve object in testInAppNotification Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Removing improper options for NotificationpreferencesView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Adding API version Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Use redux in UserNotificationPrefView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Remove in app test Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Use components from another view Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Removing verification for testing in-app notifications Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Move to ProfileView Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-08-21 13:30:11 +00:00
import { DrawerButton, PreferencesButton } from '../../containers/HeaderButton';
2019-03-12 16:23:06 +00:00
import StatusBar from '../../containers/StatusBar';
2019-12-04 16:39:53 +00:00
import { themes } from '../../constants/colors';
import { withTheme } from '../../theme';
2020-02-11 14:09:14 +00:00
import { getUserSelector } from '../../selectors/login';
[CHORE] Update react-navigation to v5 (#2154) * react-navigation v5 installed * compiling * Outside working * InsideStack compiling * Switch stack * Starting room * RoomView header * SafeAreaView * Slide from right stack animation * stash * Fix params * Create channel * inapp notification * Custom status * Add server working * Refactor appStart * Attachment * in-app notification * AuthLoadingView * Remove compat * Navigation * Outside animations * Fix new server icon * block modal * AttachmentView header * Remove unnecessary code * SelectedUsersView header * StatusView * CreateDiscussionView * RoomInfoView * RoomInfoEditView style * RoomMembersView * RoomsListView header * RoomView header * Share extension * getParam * Focus/blur * Trying to fix inapp * Lint * Simpler app container * Update libs * Revert "Simpler app container" This reverts commit 1e49d80bb49481c34f415831b9da5e9d53e66057. * Load messages faster * Fix safearea on ReactionsModal * Update safe area to v3 * lint * Fix transition * stash - drawer replace working * stash - modal nav * RoomActionsView as tablet modal * RoomStack * Stop showing RoomView header when there's no room * Custom Header and different navigation based on stack * Refactor setHeader * MasterDetailContext * RoomView header * Fix isMasterDetail rule * KeyCommands kind of working * Create channel on tablet * RoomView sCU * Remove withSplit * Settings opening as modal * Settings * StatusView headerLeft * Admin panel * TwoFactor style * DirectoryView * ServerDropdown and SortDropdown animations * ThreadMessagesView * Navigate to empty RoomView on server switch when in master detail * ProfileView header * Fix navigation issues * Nav to any room info on tablet * Room info * Refactoring * Fix rooms search * Roomslist commands * SearchMessagesView close modal * Key commands * Fix undefined subscription * Disallow navigate to focused room * isFocused state on RoomsListView * Blur text inputs when focus is lost * Replace animation * Default nav theme * Refactoring * Always open Attachment with close modal button * ModalContainer backdrop following themes * Screen tracking * Refactor get active route for in-app notification * Only mark room as focused when in master detail layout * Lint * Open modals as fade from bottom on Android * typo * Fixing tests * Fix in-app update * Fixing goRoom issues * Refactor stack names * Fix unreadsCount * Fix stack * Fix header animation * Refactor ShareNavigation * Refactor navigation theme * Make sure title is set * Fix create discussion navigation * Remove unused variable * Create discussions from actions fixed * Layout animation * Screen lock on share extension * Unnecessary change * Admin border * Set header after state callback * Fix key commands on outside stack * Fix back button pressed * Remove layout animations from Android * Tweak animations on Android * Disable swipe gesture to open drawer * Fix current item on RoomsListView * Fix add server * Fix drawer * Fix broadcast * LayoutAnimation instead of Transitions * Fix onboarding back press * Fix assorted tests * Create discussion fix * RoomInfoView header * Drawer active item
2020-06-15 14:00:46 +00:00
import SafeAreaView from '../../containers/SafeAreaView';
2018-06-05 01:17:02 +00:00
class ProfileView extends React.Component {
[CHORE] Update react-navigation to v5 (#2154) * react-navigation v5 installed * compiling * Outside working * InsideStack compiling * Switch stack * Starting room * RoomView header * SafeAreaView * Slide from right stack animation * stash * Fix params * Create channel * inapp notification * Custom status * Add server working * Refactor appStart * Attachment * in-app notification * AuthLoadingView * Remove compat * Navigation * Outside animations * Fix new server icon * block modal * AttachmentView header * Remove unnecessary code * SelectedUsersView header * StatusView * CreateDiscussionView * RoomInfoView * RoomInfoEditView style * RoomMembersView * RoomsListView header * RoomView header * Share extension * getParam * Focus/blur * Trying to fix inapp * Lint * Simpler app container * Update libs * Revert "Simpler app container" This reverts commit 1e49d80bb49481c34f415831b9da5e9d53e66057. * Load messages faster * Fix safearea on ReactionsModal * Update safe area to v3 * lint * Fix transition * stash - drawer replace working * stash - modal nav * RoomActionsView as tablet modal * RoomStack * Stop showing RoomView header when there's no room * Custom Header and different navigation based on stack * Refactor setHeader * MasterDetailContext * RoomView header * Fix isMasterDetail rule * KeyCommands kind of working * Create channel on tablet * RoomView sCU * Remove withSplit * Settings opening as modal * Settings * StatusView headerLeft * Admin panel * TwoFactor style * DirectoryView * ServerDropdown and SortDropdown animations * ThreadMessagesView * Navigate to empty RoomView on server switch when in master detail * ProfileView header * Fix navigation issues * Nav to any room info on tablet * Room info * Refactoring * Fix rooms search * Roomslist commands * SearchMessagesView close modal * Key commands * Fix undefined subscription * Disallow navigate to focused room * isFocused state on RoomsListView * Blur text inputs when focus is lost * Replace animation * Default nav theme * Refactoring * Always open Attachment with close modal button * ModalContainer backdrop following themes * Screen tracking * Refactor get active route for in-app notification * Only mark room as focused when in master detail layout * Lint * Open modals as fade from bottom on Android * typo * Fixing tests * Fix in-app update * Fixing goRoom issues * Refactor stack names * Fix unreadsCount * Fix stack * Fix header animation * Refactor ShareNavigation * Refactor navigation theme * Make sure title is set * Fix create discussion navigation * Remove unused variable * Create discussions from actions fixed * Layout animation * Screen lock on share extension * Unnecessary change * Admin border * Set header after state callback * Fix key commands on outside stack * Fix back button pressed * Remove layout animations from Android * Tweak animations on Android * Disable swipe gesture to open drawer * Fix current item on RoomsListView * Fix add server * Fix drawer * Fix broadcast * LayoutAnimation instead of Transitions * Fix onboarding back press * Fix assorted tests * Create discussion fix * RoomInfoView header * Drawer active item
2020-06-15 14:00:46 +00:00
static navigationOptions = ({ navigation, isMasterDetail }) => {
const options = {
title: I18n.t('Profile')
};
if (!isMasterDetail) {
options.headerLeft = () => <DrawerButton navigation={navigation} />;
}
[NEW] User notification preferences (#2403) * Button to preferences view Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Create screen to preferences and listItem to notifications Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Refactoring NotificationPreferencesView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * List notification preferences Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Adding translations to labels Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * SetUserPreferences api call Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Saving new user preference in API Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Fix lint Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Add in-app notification test Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Fix in app mentions preference Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Improve object in testInAppNotification Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Removing improper options for NotificationpreferencesView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Adding API version Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Use redux in UserNotificationPrefView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Remove in app test Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Use components from another view Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Removing verification for testing in-app notifications Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Move to ProfileView Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-08-21 13:30:11 +00:00
options.headerRight = () => (
<PreferencesButton onPress={() => navigation.navigate('UserPreferencesView')} testID='preferences-view-open' />
[NEW] User notification preferences (#2403) * Button to preferences view Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Create screen to preferences and listItem to notifications Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Refactoring NotificationPreferencesView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * List notification preferences Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Adding translations to labels Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * SetUserPreferences api call Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Saving new user preference in API Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Fix lint Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Add in-app notification test Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Fix in app mentions preference Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Improve object in testInAppNotification Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Removing improper options for NotificationpreferencesView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Adding API version Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Use redux in UserNotificationPrefView Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Remove in app test Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Use components from another view Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Removing verification for testing in-app notifications Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> * Move to ProfileView Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-08-21 13:30:11 +00:00
);
[CHORE] Update react-navigation to v5 (#2154) * react-navigation v5 installed * compiling * Outside working * InsideStack compiling * Switch stack * Starting room * RoomView header * SafeAreaView * Slide from right stack animation * stash * Fix params * Create channel * inapp notification * Custom status * Add server working * Refactor appStart * Attachment * in-app notification * AuthLoadingView * Remove compat * Navigation * Outside animations * Fix new server icon * block modal * AttachmentView header * Remove unnecessary code * SelectedUsersView header * StatusView * CreateDiscussionView * RoomInfoView * RoomInfoEditView style * RoomMembersView * RoomsListView header * RoomView header * Share extension * getParam * Focus/blur * Trying to fix inapp * Lint * Simpler app container * Update libs * Revert "Simpler app container" This reverts commit 1e49d80bb49481c34f415831b9da5e9d53e66057. * Load messages faster * Fix safearea on ReactionsModal * Update safe area to v3 * lint * Fix transition * stash - drawer replace working * stash - modal nav * RoomActionsView as tablet modal * RoomStack * Stop showing RoomView header when there's no room * Custom Header and different navigation based on stack * Refactor setHeader * MasterDetailContext * RoomView header * Fix isMasterDetail rule * KeyCommands kind of working * Create channel on tablet * RoomView sCU * Remove withSplit * Settings opening as modal * Settings * StatusView headerLeft * Admin panel * TwoFactor style * DirectoryView * ServerDropdown and SortDropdown animations * ThreadMessagesView * Navigate to empty RoomView on server switch when in master detail * ProfileView header * Fix navigation issues * Nav to any room info on tablet * Room info * Refactoring * Fix rooms search * Roomslist commands * SearchMessagesView close modal * Key commands * Fix undefined subscription * Disallow navigate to focused room * isFocused state on RoomsListView * Blur text inputs when focus is lost * Replace animation * Default nav theme * Refactoring * Always open Attachment with close modal button * ModalContainer backdrop following themes * Screen tracking * Refactor get active route for in-app notification * Only mark room as focused when in master detail layout * Lint * Open modals as fade from bottom on Android * typo * Fixing tests * Fix in-app update * Fixing goRoom issues * Refactor stack names * Fix unreadsCount * Fix stack * Fix header animation * Refactor ShareNavigation * Refactor navigation theme * Make sure title is set * Fix create discussion navigation * Remove unused variable * Create discussions from actions fixed * Layout animation * Screen lock on share extension * Unnecessary change * Admin border * Set header after state callback * Fix key commands on outside stack * Fix back button pressed * Remove layout animations from Android * Tweak animations on Android * Disable swipe gesture to open drawer * Fix current item on RoomsListView * Fix add server * Fix drawer * Fix broadcast * LayoutAnimation instead of Transitions * Fix onboarding back press * Fix assorted tests * Create discussion fix * RoomInfoView header * Drawer active item
2020-06-15 14:00:46 +00:00
return options;
}
static propTypes = {
baseUrl: PropTypes.string,
user: PropTypes.object,
Accounts_AllowEmailChange: PropTypes.bool,
Accounts_AllowPasswordChange: PropTypes.bool,
Accounts_AllowRealNameChange: PropTypes.bool,
Accounts_AllowUserAvatarChange: PropTypes.bool,
Accounts_AllowUsernameChange: PropTypes.bool,
Accounts_CustomFields: PropTypes.string,
2019-12-04 16:39:53 +00:00
setUser: PropTypes.func,
theme: PropTypes.string
}
state = {
saving: false,
name: null,
username: null,
email: null,
newPassword: null,
currentPassword: null,
avatarUrl: null,
avatar: {},
avatarSuggestions: {},
customFields: {}
}
async componentDidMount() {
this.init();
try {
const result = await RocketChat.getAvatarSuggestion();
this.setState({ avatarSuggestions: result });
} catch (e) {
log(e);
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
const { user } = this.props;
/*
* We need to ignore status because on Android ImagePicker
* changes the activity, so, the user status changes and
* it's resetting the avatar right after
* select some image from gallery.
*/
if (!isEqual(omit(user, ['status']), omit(nextProps.user, ['status']))) {
this.init(nextProps.user);
}
}
shouldComponentUpdate(nextProps, nextState) {
if (!isEqual(nextState, this.state)) {
return true;
}
if (!isEqual(nextProps, this.props)) {
return true;
}
return false;
}
setAvatar = (avatar) => {
const { Accounts_AllowUserAvatarChange } = this.props;
if (!Accounts_AllowUserAvatarChange) {
return;
}
this.setState({ avatar });
}
init = (user) => {
const { user: userProps } = this.props;
const {
name, username, emails, customFields
} = user || userProps;
this.setState({
name,
username,
email: emails ? emails[0].address : null,
newPassword: null,
currentPassword: null,
avatarUrl: null,
avatar: {},
customFields: customFields || {}
});
}
formIsChanged = () => {
const {
name, username, email, newPassword, avatar, customFields
} = this.state;
const { user } = this.props;
let customFieldsChanged = false;
const customFieldsKeys = Object.keys(customFields);
if (customFieldsKeys.length) {
customFieldsKeys.forEach((key) => {
if (!user.customFields || user.customFields[key] !== customFields[key]) {
customFieldsChanged = true;
}
});
}
return !(user.name === name
&& user.username === username
&& !newPassword
&& (user.emails && user.emails[0].address === email)
&& !avatar.data
&& !customFieldsChanged
);
}
handleError = (e, func, action) => {
if (e.data && e.data.error.includes('[error-too-many-requests]')) {
return showErrorAlert(e.data.error);
}
2020-03-03 20:27:38 +00:00
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t(action) }));
}
submit = async() => {
Keyboard.dismiss();
if (!this.formIsChanged()) {
return;
}
this.setState({ saving: true });
const {
name, username, email, newPassword, currentPassword, avatar, customFields
} = this.state;
const { user, setUser } = this.props;
const params = {};
// Name
if (user.name !== name) {
params.name = name;
}
// Username
if (user.username !== username) {
params.username = username;
}
// Email
if (user.emails && user.emails[0].address !== email) {
params.email = email;
}
// newPassword
if (newPassword) {
params.newPassword = newPassword;
}
// currentPassword
if (currentPassword) {
params.currentPassword = SHA256(currentPassword);
}
const requirePassword = !!params.email || newPassword;
if (requirePassword && !params.currentPassword) {
2020-03-03 20:27:38 +00:00
this.setState({ saving: false });
prompt(
I18n.t('Please_enter_your_password'),
I18n.t('For_your_security_you_must_enter_your_current_password_to_continue'),
[
{ text: I18n.t('Cancel'), onPress: () => {}, style: 'cancel' },
{
text: I18n.t('Save'),
onPress: (p) => {
this.setState({ currentPassword: p });
this.submit();
}
}
],
{
type: 'secure-text',
cancelable: false
}
);
return;
}
try {
if (avatar.url) {
try {
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
logEvent(events.PROFILE_SAVE_AVATAR);
await RocketChat.setAvatarFromService(avatar);
} catch (e) {
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
logEvent(events.PROFILE_SAVE_AVATAR_F);
this.setState({ saving: false, currentPassword: null });
return this.handleError(e, 'setAvatarFromService', 'changing_avatar');
}
}
2019-06-05 16:29:07 +00:00
const result = await RocketChat.saveUserProfile(params, customFields);
if (result.success) {
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
logEvent(events.PROFILE_SAVE_CHANGES);
2019-06-05 16:29:07 +00:00
if (customFields) {
setUser({ customFields, ...params });
} else {
setUser({ ...params });
}
2019-07-23 14:02:57 +00:00
EventEmitter.emit(LISTENER, { message: I18n.t('Profile_saved_successfully') });
this.init();
}
this.setState({ saving: false });
} catch (e) {
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
logEvent(events.PROFILE_SAVE_CHANGES_F);
this.setState({ saving: false, currentPassword: null });
this.handleError(e, 'saveUserProfile', 'saving_profile');
}
}
resetAvatar = async() => {
const { Accounts_AllowUserAvatarChange } = this.props;
if (!Accounts_AllowUserAvatarChange) {
return;
}
try {
const { user } = this.props;
await RocketChat.resetAvatar(user.id);
2019-07-23 14:02:57 +00:00
EventEmitter.emit(LISTENER, { message: I18n.t('Avatar_changed_successfully') });
this.init();
} catch (e) {
this.handleError(e, 'resetAvatar', 'changing_avatar');
}
}
pickImage = async() => {
const { Accounts_AllowUserAvatarChange } = this.props;
if (!Accounts_AllowUserAvatarChange) {
return;
}
const options = {
cropping: true,
compressImageQuality: 0.8,
freeStyleCropEnabled: true,
cropperAvoidEmptySpaceAroundImage: false,
cropperChooseText: I18n.t('Choose'),
cropperCancelText: I18n.t('Cancel'),
includeBase64: true
};
try {
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
logEvent(events.PROFILE_PICK_AVATAR);
const response = await ImagePicker.openPicker(options);
this.setAvatar({ url: response.path, data: `data:image/jpeg;base64,${ response.data }`, service: 'upload' });
} catch (error) {
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
logEvent(events.PROFILE_PICK_AVATAR_F);
console.warn(error);
}
}
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
pickImageWithURL = (avatarUrl) => {
logEvent(events.PROFILE_PICK_AVATAR_WITH_URL);
this.setAvatar({ url: avatarUrl, data: avatarUrl, service: 'url' });
}
renderAvatarButton = ({
key, child, onPress, disabled = false
2019-12-04 16:39:53 +00:00
}) => {
const { theme } = this.props;
return (
<Touch
key={key}
testID={key}
onPress={onPress}
style={[styles.avatarButton, { opacity: disabled ? 0.5 : 1 }, { backgroundColor: themes[theme].borderColor }]}
enabled={!disabled}
theme={theme}
>
{child}
2019-12-04 16:39:53 +00:00
</Touch>
);
}
renderAvatarButtons = () => {
const { avatarUrl, avatarSuggestions } = this.state;
const {
user,
theme,
Accounts_AllowUserAvatarChange
} = this.props;
return (
<View style={styles.avatarButtons}>
{this.renderAvatarButton({
child: <Avatar text={`@${ user.username }`} size={50} />,
onPress: () => this.resetAvatar(),
disabled: !Accounts_AllowUserAvatarChange,
key: 'profile-view-reset-avatar'
})}
{this.renderAvatarButton({
2019-12-04 16:39:53 +00:00
child: <CustomIcon name='upload' size={30} color={themes[theme].bodyText} />,
onPress: () => this.pickImage(),
disabled: !Accounts_AllowUserAvatarChange,
key: 'profile-view-upload-avatar'
})}
{this.renderAvatarButton({
child: <CustomIcon name='link' size={30} color={themes[theme].bodyText} />,
[NEW] Log events from RoomsList, SideDrawer and Profile (#2190) * Create method to track user event to isolate the logic to improve future refactoring * Track Onboarding view * Track NewServer view * Refactor track method due to firebase already send the current screen * Track default login and all the oAuth options * Track default sign up in RegisterView * Change trackUserEvent signature and update all the files * Track the remaining login services * track add server, change server and search * Track SidebarView and refactor to use react-navigation * Track profile events and handle exceptions * Track create channel flux * Track send message to user via NewMessageView * Track create direct message flux * Handle failure of create channel and group in the saga * Track create discussion flux * Track navigate to directory and its actions * Track read, favorite and hide a channel, handling its errors * Track all channels sorting and grouping * Resolve requests to improve the importing logs and events * Remove unused events file * Leave a bugsnag breadcrumb when logging an event * Move all logEvent to the top of code block and log remaining fail events * Move all the non-logic-dependent logEvent to the top of code block * Improve the logging of sidebar events * Improve events from onboarding and newserver * Improve events from login and register view, and log enter with apple * Improve NewMessageView events * Improve CreateChannel events * Improve CreateDiscussion and SelectedUsers create group events * Improve RoomsList events and log trivial events * Improve ProfileView events * Remove single line function body for the sidebarNavigate * Navigate to Status and AdminPanel View using the defined sidebarNavigate method Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-07-30 13:26:17 +00:00
onPress: () => this.pickImageWithURL(avatarUrl),
disabled: !avatarUrl,
key: 'profile-view-avatar-url-button'
})}
{Object.keys(avatarSuggestions).map((service) => {
const { url, blob, contentType } = avatarSuggestions[service];
return this.renderAvatarButton({
disabled: !Accounts_AllowUserAvatarChange,
key: `profile-view-avatar-${ service }`,
child: <Avatar avatar={url} size={50} />,
onPress: () => this.setAvatar({
url, data: blob, service, contentType
})
});
})}
</View>
);
}
renderCustomFields = () => {
const { customFields } = this.state;
2019-12-04 16:39:53 +00:00
const { Accounts_CustomFields, theme } = this.props;
if (!Accounts_CustomFields) {
return null;
}
try {
const parsedCustomFields = JSON.parse(Accounts_CustomFields);
return Object.keys(parsedCustomFields).map((key, index, array) => {
if (parsedCustomFields[key].type === 'select') {
const options = parsedCustomFields[key].options.map(option => ({ label: option, value: option }));
return (
<RNPickerSelect
key={key}
items={options}
onValueChange={(value) => {
const newValue = {};
newValue[key] = value;
this.setState({ customFields: { ...customFields, ...newValue } });
}}
value={customFields[key]}
>
<RCTextInput
inputRef={(e) => { this[key] = e; }}
label={key}
placeholder={key}
value={customFields[key]}
testID='settings-view-language'
2019-12-04 16:39:53 +00:00
theme={theme}
/>
</RNPickerSelect>
);
}
return (
<RCTextInput
inputRef={(e) => { this[key] = e; }}
key={key}
label={key}
placeholder={key}
value={customFields[key]}
onChangeText={(value) => {
const newValue = {};
newValue[key] = value;
this.setState({ customFields: { ...customFields, ...newValue } });
}}
onSubmitEditing={() => {
if (array.length - 1 > index) {
return this[array[index + 1]].focus();
}
this.avatarUrl.focus();
}}
2019-12-04 16:39:53 +00:00
theme={theme}
/>
);
});
} catch (error) {
return null;
}
2018-06-05 01:17:02 +00:00
}
logoutOtherLocations = () => {
logEvent(events.PROFILE_LOGOUT_OTHER_LOCATIONS);
showConfirmationAlert({
message: I18n.t('You_will_be_logged_out_from_other_locations'),
callToAction: I18n.t('Logout'),
onPress: async() => {
try {
await RocketChat.logoutOtherLocations();
EventEmitter.emit(LISTENER, { message: I18n.t('Logged_out_of_other_clients_successfully') });
} catch {
logEvent(events.PROFILE_LOGOUT_OTHER_LOCATIONS_F);
EventEmitter.emit(LISTENER, { message: I18n.t('Logout_failed') });
}
}
});
}
2018-06-05 01:17:02 +00:00
render() {
const {
2020-03-03 20:27:38 +00:00
name, username, email, newPassword, avatarUrl, customFields, avatar, saving
} = this.state;
2019-12-04 16:39:53 +00:00
const {
user,
theme,
Accounts_AllowEmailChange,
Accounts_AllowPasswordChange,
Accounts_AllowRealNameChange,
Accounts_AllowUserAvatarChange,
Accounts_AllowUsernameChange,
Accounts_CustomFields
2019-12-04 16:39:53 +00:00
} = this.props;
2018-06-05 01:17:02 +00:00
return (
<KeyboardView
2019-12-04 16:39:53 +00:00
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
contentContainerStyle={sharedStyles.container}
keyboardVerticalOffset={128}
>
<StatusBar />
<SafeAreaView testID='profile-view'>
2019-12-04 16:39:53 +00:00
<ScrollView
contentContainerStyle={sharedStyles.containerScrollView}
testID='profile-view-list'
{...scrollPersistTaps}
>
<View style={styles.avatarContainer} testID='profile-view-avatar'>
<Avatar
text={user.username}
avatar={avatar?.url}
isStatic={avatar?.url}
size={100}
/>
</View>
<RCTextInput
editable={Accounts_AllowRealNameChange}
inputStyle={[
!Accounts_AllowRealNameChange && styles.disabled
]}
inputRef={(e) => { this.name = e; }}
label={I18n.t('Name')}
placeholder={I18n.t('Name')}
value={name}
onChangeText={value => this.setState({ name: value })}
onSubmitEditing={() => { this.username.focus(); }}
testID='profile-view-name'
2019-12-04 16:39:53 +00:00
theme={theme}
/>
<RCTextInput
editable={Accounts_AllowUsernameChange}
inputStyle={[
!Accounts_AllowUsernameChange && styles.disabled
]}
inputRef={(e) => { this.username = e; }}
label={I18n.t('Username')}
placeholder={I18n.t('Username')}
value={username}
onChangeText={value => this.setState({ username: value })}
onSubmitEditing={() => { this.email.focus(); }}
testID='profile-view-username'
2019-12-04 16:39:53 +00:00
theme={theme}
/>
<RCTextInput
editable={Accounts_AllowEmailChange}
inputStyle={[
!Accounts_AllowEmailChange && styles.disabled
]}
inputRef={(e) => { this.email = e; }}
label={I18n.t('Email')}
placeholder={I18n.t('Email')}
value={email}
onChangeText={value => this.setState({ email: value })}
onSubmitEditing={() => { this.newPassword.focus(); }}
testID='profile-view-email'
2019-12-04 16:39:53 +00:00
theme={theme}
/>
<RCTextInput
editable={Accounts_AllowPasswordChange}
inputStyle={[
!Accounts_AllowPasswordChange && styles.disabled
]}
inputRef={(e) => { this.newPassword = e; }}
label={I18n.t('New_Password')}
placeholder={I18n.t('New_Password')}
value={newPassword}
onChangeText={value => this.setState({ newPassword: value })}
onSubmitEditing={() => {
if (Accounts_CustomFields && Object.keys(customFields).length) {
return this[Object.keys(customFields)[0]].focus();
}
this.avatarUrl.focus();
}}
secureTextEntry
testID='profile-view-new-password'
2019-12-04 16:39:53 +00:00
theme={theme}
/>
{this.renderCustomFields()}
<RCTextInput
editable={Accounts_AllowUserAvatarChange}
inputStyle={[
!Accounts_AllowUserAvatarChange && styles.disabled
]}
inputRef={(e) => { this.avatarUrl = e; }}
label={I18n.t('Avatar_Url')}
placeholder={I18n.t('Avatar_Url')}
value={avatarUrl}
onChangeText={value => this.setState({ avatarUrl: value })}
onSubmitEditing={this.submit}
testID='profile-view-avatar-url'
2019-12-04 16:39:53 +00:00
theme={theme}
/>
{this.renderAvatarButtons()}
<Button
title={I18n.t('Save_Changes')}
type='primary'
onPress={this.submit}
disabled={!this.formIsChanged()}
testID='profile-view-submit'
loading={saving}
2019-12-04 16:39:53 +00:00
theme={theme}
/>
<Button
title={I18n.t('Logout_from_other_logged_in_locations')}
type='secondary'
backgroundColor={themes[theme].chatComponentBackground}
onPress={this.logoutOtherLocations}
testID='profile-view-logout-other-locations'
theme={theme}
/>
2019-12-04 16:39:53 +00:00
</ScrollView>
</SafeAreaView>
</KeyboardView>
2018-06-05 01:17:02 +00:00
);
}
}
const mapStateToProps = state => ({
2020-02-11 14:09:14 +00:00
user: getUserSelector(state),
Accounts_AllowEmailChange: state.settings.Accounts_AllowEmailChange,
Accounts_AllowPasswordChange: state.settings.Accounts_AllowPasswordChange,
Accounts_AllowRealNameChange: state.settings.Accounts_AllowRealNameChange,
Accounts_AllowUserAvatarChange: state.settings.Accounts_AllowUserAvatarChange,
Accounts_AllowUsernameChange: state.settings.Accounts_AllowUsernameChange,
Accounts_CustomFields: state.settings.Accounts_CustomFields,
2020-02-11 14:09:14 +00:00
baseUrl: state.server.server
});
const mapDispatchToProps = dispatch => ({
setUser: params => dispatch(setUserAction(params))
});
2019-12-04 16:39:53 +00:00
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(ProfileView));