verdnatura-chat/app/views/ProfileView/index.js

495 lines
14 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';
import Dialog from 'react-native-dialog';
import SHA256 from 'js-sha256';
import ImagePicker from 'react-native-image-crop-picker';
import RNPickerSelect from 'react-native-picker-select';
2019-03-12 16:23:06 +00:00
import { SafeAreaView } from 'react-navigation';
import equal from 'deep-equal';
2018-06-05 01:17:02 +00:00
import KeyboardView from '../../presentation/KeyboardView';
import sharedStyles from '../Styles';
import styles from './styles';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
[RELEASE] Merge beta into master (#1082) * Bump version to 1.16.0 (#1014) * [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982) * :sparkles: Create user table * :sparkles: Introduce user table * :fire: Remove unused table * :heavy_plus_sign: Add userdefaults to storage data * :green_heart: Fix android build * :sparkles: Get credentials from iOS native client * :fire: Remove unused code * :rewind: Revert sign xcode * :bug: Fix first login-logout * :art: Use constants to UserDefaults Keys * :bug: Fix clear server-user-info on logout * :bug: Fix filter null value * :ambulance: Remove user object in logout * :sparkles: Fix get servers from native-client * :ambulance: Fix error on change server * [FIX] Don't run UserDefaults credentials on Android (#1015) * :bug: Fix native credentials (android) * Fix migration loop * [IMPROVEMENT] Hide frequently used emoji tab when empty (#792) * [IMPROVEMENT] Bigger emoji in emoji only messages (#793) * issue #725: bigger emoji in emoji only message * issue-725/add storybook for Message/Emoji * issue-725: update storybook/Message jest snapshot * comment storybook import * allow spaces and line breaks in emoji only message * merge develop * revert unnecessary spacing * [FIX] Empty message if contains only a link (#787) * Fix empty message if contains only a link * :bug: Fix empty space * [IMPROVEMENT] Refactor empty space regex on quote (#1017) * :art: Improve regex to empty space on quote * :art: Improve on regex to empty space on quote * [NEW] Custom fields on signup (#1013) * added custom feilds on registration * added flag as leftIcon and removed lable * added try and catch * typo * [CHORE] Renew provisioning profiles (#1020) * [NEW] Auto-translate (#1012) * Update realm * View original and translate working * Read AutoTranslate_Enabled setting * RocketChat.canAutoTranslate() * AutoTranslateView * Save language * Auto-translate switch * Translate message * [IMPROVEMENT] Use haptics rather than vibration (#1016) * Install expo-haptics * Use expo-haptics rather than RN's Vibration module * [IMPROVEMENT] Use Rest API for file upload (#1005) * removed rn-fetch-blob and use native XMLHttpRequest instead * removed unnessary changes * fix android bug * fix android bug * added tmid support * fix bug * fixed isssue with cacel model * fix problems with audio * done requested changes * fix bug with android * [CHORE] [CI] [TESTS] update detox to make ci pass (#1026) * feat: update detox to 12.11.3 to make CI pass * ci: comment all jobs but leave e2e-test job * commit to rerun IC e2e-test job * ci: uncomment all CI jobs * [NEW] Room swipe actions: mark as read/unread, hide, fav (#976) * added unread and fav feature * changed the layout * fix jest * done requested changes * added requested changes * [FIX] Android build (#1027) * [FIX] Android build * CircleCI error * [FIX] iOS share credentials build (#1028) * [FIX] iOS share credentials build * Use `hasMigration` as a string * [CI] Restore cache on CI (#1029) * feat: add fastlane save\restore cache config; comment not needed jobs; * install fastlane using 'bundle install' * install fastlane using 'sudo bundle install' * uncomment ios build commands * run set up google services in ios folder * add working_directory: ios to ios-build steps * remove 'cd ios' from Fastlane build step * add save\restore cache for npm modules * group save_cache steps * cache fastlane in ios-testflight job * uncomment previously commented jobs\steps * fix: add missing colon * use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }} * add names for save\restore steps * ci: add `default` step with `working_directory: ~/repo` to ios-build job * return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}` * fix: add missing curly braces * save\restore cache in e2e-test job; remove {{arch}} from cache names * add names to restore_cache steps in android-build job * add names to save_cache steps in android-build job * add names to all save\restore steps; change checksum package.json to yarn.lock * change `npm` to `NPM` in steps naming * remove {{ checksum circle ci }} from android-build job and fix naming of steps * [FIX] Rooms swipes (#1034) * Regression: on press style feedback * Action button styles * Fix animations * Styles changed * Update subscription without having to wait for socket * Calculate width on RoomsListView instead * [FIX] Decrease bigger emoji size to 30 (#1031) * [FIX] Append server URL on avatar if necessary (#1038) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Bump version to 1.16.1 (#1045) * [FIX] Set UserDefaults AppGroup on notification tap (#1047) * [FIX] Auto-translate messages as they arrive * Fix favorite button * [FIX] Swipe animations (#1044) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Fix favorite button * [FIX] Auto-translate messages as they arrive (#1049) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * [FIX] Auto-translate messages as they arrive * [i18n] Add missing de translations (#1040) * [CHORE] Switch to react-native-localize (#1043) * Bump version to 1.17.0 (#1057) * Load views as needed (#1056) * [IMPROVEMENT] Change "resend" icon position (#1048) * [NEW] Video support (#801) * [NEW] File upload (#882) * [NEW] Share extension (#942) * [FIX] Share extension CI build (#1060) * Change bundleID * Provisioning * get provisioning profile * [IMPROVEMENT] Reusable toast (#1065) * [FIX] Moment locales (#1066) * [FIX] Share Extension issues (#1064) * [FIX] Empty white list enables all media types upload (#1077) * Merge branch 'master' into develop (#1079) * [FIX] Empty white list enables all media types upload (#1080) * Create utils to media (canUpload) * Fix variable name * [CHORE] Update README (#1081)
2019-07-29 20:44:39 +00:00
import { showErrorAlert } from '../../utils/info';
import { LISTENER } from '../../containers/Toast';
import EventEmitter from '../../utils/events';
import RocketChat from '../../lib/rocketchat';
import RCTextInput from '../../containers/TextInput';
import log from '../../utils/log';
import I18n from '../../i18n';
import Button from '../../containers/Button';
import Avatar from '../../containers/Avatar';
import Touch from '../../utils/touch';
import { setUser as setUserAction } from '../../actions/login';
import { CustomIcon } from '../../lib/Icons';
2019-03-12 16:23:06 +00:00
import { DrawerButton } from '../../containers/HeaderButton';
import StatusBar from '../../containers/StatusBar';
2019-03-29 19:36:07 +00:00
import { COLOR_TEXT } from '../../constants/colors';
2018-06-05 01:17:02 +00:00
class ProfileView extends React.Component {
2019-03-12 16:23:06 +00:00
static navigationOptions = ({ navigation }) => ({
headerLeft: <DrawerButton navigation={navigation} />,
title: I18n.t('Profile')
})
static propTypes = {
baseUrl: PropTypes.string,
user: PropTypes.object,
Accounts_CustomFields: PropTypes.string,
setUser: PropTypes.func
}
state = {
showPasswordAlert: false,
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);
}
}
componentWillReceiveProps(nextProps) {
const { user } = this.props;
if (user !== nextProps.user) {
this.init(nextProps.user);
}
}
shouldComponentUpdate(nextProps, nextState) {
if (!equal(nextState, this.state)) {
return true;
}
if (!equal(nextProps, this.props)) {
return true;
}
return false;
}
setAvatar = (avatar) => {
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
);
}
closePasswordAlert = () => {
this.setState({ showPasswordAlert: false });
}
handleError = (e, func, action) => {
if (e.data && e.data.errorType === 'error-too-many-requests') {
return showErrorAlert(e.data.error);
}
showErrorAlert(
I18n.t('There_was_an_error_while_action', { action: I18n.t(action) }),
'',
() => this.setState({ showPasswordAlert: false })
);
}
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) {
return this.setState({ showPasswordAlert: true, saving: false });
}
try {
if (avatar.url) {
try {
await RocketChat.setAvatarFromService(avatar);
} catch (e) {
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) {
2019-06-05 16:29:07 +00:00
if (customFields) {
setUser({ customFields, ...params });
} else {
setUser({ ...params });
}
this.setState({ saving: false, showPasswordAlert: false });
[RELEASE] Merge beta into master (#1082) * Bump version to 1.16.0 (#1014) * [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982) * :sparkles: Create user table * :sparkles: Introduce user table * :fire: Remove unused table * :heavy_plus_sign: Add userdefaults to storage data * :green_heart: Fix android build * :sparkles: Get credentials from iOS native client * :fire: Remove unused code * :rewind: Revert sign xcode * :bug: Fix first login-logout * :art: Use constants to UserDefaults Keys * :bug: Fix clear server-user-info on logout * :bug: Fix filter null value * :ambulance: Remove user object in logout * :sparkles: Fix get servers from native-client * :ambulance: Fix error on change server * [FIX] Don't run UserDefaults credentials on Android (#1015) * :bug: Fix native credentials (android) * Fix migration loop * [IMPROVEMENT] Hide frequently used emoji tab when empty (#792) * [IMPROVEMENT] Bigger emoji in emoji only messages (#793) * issue #725: bigger emoji in emoji only message * issue-725/add storybook for Message/Emoji * issue-725: update storybook/Message jest snapshot * comment storybook import * allow spaces and line breaks in emoji only message * merge develop * revert unnecessary spacing * [FIX] Empty message if contains only a link (#787) * Fix empty message if contains only a link * :bug: Fix empty space * [IMPROVEMENT] Refactor empty space regex on quote (#1017) * :art: Improve regex to empty space on quote * :art: Improve on regex to empty space on quote * [NEW] Custom fields on signup (#1013) * added custom feilds on registration * added flag as leftIcon and removed lable * added try and catch * typo * [CHORE] Renew provisioning profiles (#1020) * [NEW] Auto-translate (#1012) * Update realm * View original and translate working * Read AutoTranslate_Enabled setting * RocketChat.canAutoTranslate() * AutoTranslateView * Save language * Auto-translate switch * Translate message * [IMPROVEMENT] Use haptics rather than vibration (#1016) * Install expo-haptics * Use expo-haptics rather than RN's Vibration module * [IMPROVEMENT] Use Rest API for file upload (#1005) * removed rn-fetch-blob and use native XMLHttpRequest instead * removed unnessary changes * fix android bug * fix android bug * added tmid support * fix bug * fixed isssue with cacel model * fix problems with audio * done requested changes * fix bug with android * [CHORE] [CI] [TESTS] update detox to make ci pass (#1026) * feat: update detox to 12.11.3 to make CI pass * ci: comment all jobs but leave e2e-test job * commit to rerun IC e2e-test job * ci: uncomment all CI jobs * [NEW] Room swipe actions: mark as read/unread, hide, fav (#976) * added unread and fav feature * changed the layout * fix jest * done requested changes * added requested changes * [FIX] Android build (#1027) * [FIX] Android build * CircleCI error * [FIX] iOS share credentials build (#1028) * [FIX] iOS share credentials build * Use `hasMigration` as a string * [CI] Restore cache on CI (#1029) * feat: add fastlane save\restore cache config; comment not needed jobs; * install fastlane using 'bundle install' * install fastlane using 'sudo bundle install' * uncomment ios build commands * run set up google services in ios folder * add working_directory: ios to ios-build steps * remove 'cd ios' from Fastlane build step * add save\restore cache for npm modules * group save_cache steps * cache fastlane in ios-testflight job * uncomment previously commented jobs\steps * fix: add missing colon * use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }} * add names for save\restore steps * ci: add `default` step with `working_directory: ~/repo` to ios-build job * return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}` * fix: add missing curly braces * save\restore cache in e2e-test job; remove {{arch}} from cache names * add names to restore_cache steps in android-build job * add names to save_cache steps in android-build job * add names to all save\restore steps; change checksum package.json to yarn.lock * change `npm` to `NPM` in steps naming * remove {{ checksum circle ci }} from android-build job and fix naming of steps * [FIX] Rooms swipes (#1034) * Regression: on press style feedback * Action button styles * Fix animations * Styles changed * Update subscription without having to wait for socket * Calculate width on RoomsListView instead * [FIX] Decrease bigger emoji size to 30 (#1031) * [FIX] Append server URL on avatar if necessary (#1038) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Bump version to 1.16.1 (#1045) * [FIX] Set UserDefaults AppGroup on notification tap (#1047) * [FIX] Auto-translate messages as they arrive * Fix favorite button * [FIX] Swipe animations (#1044) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Fix favorite button * [FIX] Auto-translate messages as they arrive (#1049) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * [FIX] Auto-translate messages as they arrive * [i18n] Add missing de translations (#1040) * [CHORE] Switch to react-native-localize (#1043) * Bump version to 1.17.0 (#1057) * Load views as needed (#1056) * [IMPROVEMENT] Change "resend" icon position (#1048) * [NEW] Video support (#801) * [NEW] File upload (#882) * [NEW] Share extension (#942) * [FIX] Share extension CI build (#1060) * Change bundleID * Provisioning * get provisioning profile * [IMPROVEMENT] Reusable toast (#1065) * [FIX] Moment locales (#1066) * [FIX] Share Extension issues (#1064) * [FIX] Empty white list enables all media types upload (#1077) * Merge branch 'master' into develop (#1079) * [FIX] Empty white list enables all media types upload (#1080) * Create utils to media (canUpload) * Fix variable name * [CHORE] Update README (#1081)
2019-07-29 20:44:39 +00:00
EventEmitter.emit(LISTENER, { message: I18n.t('Profile_saved_successfully') });
this.init();
}
} catch (e) {
this.setState({ saving: false, currentPassword: null });
this.handleError(e, 'saveUserProfile', 'saving_profile');
}
}
resetAvatar = async() => {
try {
const { user } = this.props;
await RocketChat.resetAvatar(user.id);
[RELEASE] Merge beta into master (#1082) * Bump version to 1.16.0 (#1014) * [IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982) * :sparkles: Create user table * :sparkles: Introduce user table * :fire: Remove unused table * :heavy_plus_sign: Add userdefaults to storage data * :green_heart: Fix android build * :sparkles: Get credentials from iOS native client * :fire: Remove unused code * :rewind: Revert sign xcode * :bug: Fix first login-logout * :art: Use constants to UserDefaults Keys * :bug: Fix clear server-user-info on logout * :bug: Fix filter null value * :ambulance: Remove user object in logout * :sparkles: Fix get servers from native-client * :ambulance: Fix error on change server * [FIX] Don't run UserDefaults credentials on Android (#1015) * :bug: Fix native credentials (android) * Fix migration loop * [IMPROVEMENT] Hide frequently used emoji tab when empty (#792) * [IMPROVEMENT] Bigger emoji in emoji only messages (#793) * issue #725: bigger emoji in emoji only message * issue-725/add storybook for Message/Emoji * issue-725: update storybook/Message jest snapshot * comment storybook import * allow spaces and line breaks in emoji only message * merge develop * revert unnecessary spacing * [FIX] Empty message if contains only a link (#787) * Fix empty message if contains only a link * :bug: Fix empty space * [IMPROVEMENT] Refactor empty space regex on quote (#1017) * :art: Improve regex to empty space on quote * :art: Improve on regex to empty space on quote * [NEW] Custom fields on signup (#1013) * added custom feilds on registration * added flag as leftIcon and removed lable * added try and catch * typo * [CHORE] Renew provisioning profiles (#1020) * [NEW] Auto-translate (#1012) * Update realm * View original and translate working * Read AutoTranslate_Enabled setting * RocketChat.canAutoTranslate() * AutoTranslateView * Save language * Auto-translate switch * Translate message * [IMPROVEMENT] Use haptics rather than vibration (#1016) * Install expo-haptics * Use expo-haptics rather than RN's Vibration module * [IMPROVEMENT] Use Rest API for file upload (#1005) * removed rn-fetch-blob and use native XMLHttpRequest instead * removed unnessary changes * fix android bug * fix android bug * added tmid support * fix bug * fixed isssue with cacel model * fix problems with audio * done requested changes * fix bug with android * [CHORE] [CI] [TESTS] update detox to make ci pass (#1026) * feat: update detox to 12.11.3 to make CI pass * ci: comment all jobs but leave e2e-test job * commit to rerun IC e2e-test job * ci: uncomment all CI jobs * [NEW] Room swipe actions: mark as read/unread, hide, fav (#976) * added unread and fav feature * changed the layout * fix jest * done requested changes * added requested changes * [FIX] Android build (#1027) * [FIX] Android build * CircleCI error * [FIX] iOS share credentials build (#1028) * [FIX] iOS share credentials build * Use `hasMigration` as a string * [CI] Restore cache on CI (#1029) * feat: add fastlane save\restore cache config; comment not needed jobs; * install fastlane using 'bundle install' * install fastlane using 'sudo bundle install' * uncomment ios build commands * run set up google services in ios folder * add working_directory: ios to ios-build steps * remove 'cd ios' from Fastlane build step * add save\restore cache for npm modules * group save_cache steps * cache fastlane in ios-testflight job * uncomment previously commented jobs\steps * fix: add missing colon * use key for caching: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }} * add names for save\restore steps * ci: add `default` step with `working_directory: ~/repo` to ios-build job * return back caching npm: `node-v1-{{ checksum "package.json" }}-{{ arch }}` * fix: add missing curly braces * save\restore cache in e2e-test job; remove {{arch}} from cache names * add names to restore_cache steps in android-build job * add names to save_cache steps in android-build job * add names to all save\restore steps; change checksum package.json to yarn.lock * change `npm` to `NPM` in steps naming * remove {{ checksum circle ci }} from android-build job and fix naming of steps * [FIX] Rooms swipes (#1034) * Regression: on press style feedback * Action button styles * Fix animations * Styles changed * Update subscription without having to wait for socket * Calculate width on RoomsListView instead * [FIX] Decrease bigger emoji size to 30 (#1031) * [FIX] Append server URL on avatar if necessary (#1038) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Bump version to 1.16.1 (#1045) * [FIX] Set UserDefaults AppGroup on notification tap (#1047) * [FIX] Auto-translate messages as they arrive * Fix favorite button * [FIX] Swipe animations (#1044) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * Fix favorite button * [FIX] Auto-translate messages as they arrive (#1049) * Comment removeClippedSubviews * Comment width animation * Remove redux from RoomItem * Fix wrong re-render comparison * Remove listener * Raise minDeltaX * memo actions * Spring with native driver * Refactor functions * Fix props issues * Remove RoomItem.height * Long swipe * Refactor animations * this.rowTranslation -> this.transX * Moved state to this * [FIX] Auto-translate messages as they arrive * [i18n] Add missing de translations (#1040) * [CHORE] Switch to react-native-localize (#1043) * Bump version to 1.17.0 (#1057) * Load views as needed (#1056) * [IMPROVEMENT] Change "resend" icon position (#1048) * [NEW] Video support (#801) * [NEW] File upload (#882) * [NEW] Share extension (#942) * [FIX] Share extension CI build (#1060) * Change bundleID * Provisioning * get provisioning profile * [IMPROVEMENT] Reusable toast (#1065) * [FIX] Moment locales (#1066) * [FIX] Share Extension issues (#1064) * [FIX] Empty white list enables all media types upload (#1077) * Merge branch 'master' into develop (#1079) * [FIX] Empty white list enables all media types upload (#1080) * Create utils to media (canUpload) * Fix variable name * [CHORE] Update README (#1081)
2019-07-29 20:44:39 +00:00
EventEmitter.emit(LISTENER, { message: I18n.t('Avatar_changed_successfully') });
this.init();
} catch (e) {
this.handleError(e, 'resetAvatar', 'changing_avatar');
}
}
pickImage = async() => {
const options = {
cropping: true,
compressImageQuality: 0.8,
cropperAvoidEmptySpaceAroundImage: false,
cropperChooseText: I18n.t('Choose'),
cropperCancelText: I18n.t('Cancel'),
includeBase64: true
};
try {
const response = await ImagePicker.openPicker(options);
this.setAvatar({ url: response.path, data: `data:image/jpeg;base64,${ response.data }`, service: 'upload' });
} catch (error) {
console.warn(error);
}
}
renderAvatarButton = ({
key, child, onPress, disabled = false
}) => (
<Touch
key={key}
testID={key}
onPress={onPress}
underlayColor='rgba(255, 255, 255, 0.5)'
activeOpacity={0.3}
disabled={disabled}
>
<View
style={[styles.avatarButton, { opacity: disabled ? 0.5 : 1 }]}
>
{child}
</View>
</Touch>
)
renderAvatarButtons = () => {
const { avatarUrl, avatarSuggestions } = this.state;
const { user, baseUrl } = this.props;
return (
<View style={styles.avatarButtons}>
{this.renderAvatarButton({
2019-04-18 20:57:35 +00:00
child: <Avatar text={`@${ user.username }`} size={50} baseUrl={baseUrl} userId={user.id} token={user.token} />,
onPress: () => this.resetAvatar(),
key: 'profile-view-reset-avatar'
})}
{this.renderAvatarButton({
2019-03-29 19:36:07 +00:00
child: <CustomIcon name='upload' size={30} color={COLOR_TEXT} />,
onPress: () => this.pickImage(),
key: 'profile-view-upload-avatar'
})}
{this.renderAvatarButton({
2019-03-29 19:36:07 +00:00
child: <CustomIcon name='permalink' size={30} color={COLOR_TEXT} />,
onPress: () => this.setAvatar({ url: avatarUrl, data: avatarUrl, service: 'url' }),
disabled: !avatarUrl,
key: 'profile-view-avatar-url-button'
})}
{Object.keys(avatarSuggestions).map((service) => {
const { url, blob, contentType } = avatarSuggestions[service];
return this.renderAvatarButton({
key: `profile-view-avatar-${ service }`,
2019-04-18 20:57:35 +00:00
child: <Avatar avatar={url} size={50} baseUrl={baseUrl} userId={user.id} token={user.token} />,
onPress: () => this.setAvatar({
url, data: blob, service, contentType
})
});
})}
</View>
);
}
renderCustomFields = () => {
const { customFields } = this.state;
const { Accounts_CustomFields } = 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'
/>
</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();
}}
/>
);
});
} catch (error) {
return null;
}
2018-06-05 01:17:02 +00:00
}
render() {
const {
name, username, email, newPassword, avatarUrl, customFields, avatar, saving, showPasswordAlert
} = this.state;
const { baseUrl, user } = this.props;
2018-06-05 01:17:02 +00:00
return (
<KeyboardView
contentContainerStyle={sharedStyles.container}
keyboardVerticalOffset={128}
>
2019-03-12 16:23:06 +00:00
<StatusBar />
<ScrollView
contentContainerStyle={sharedStyles.containerScrollView}
testID='profile-view-list'
{...scrollPersistTaps}
>
<SafeAreaView style={sharedStyles.container} testID='profile-view' forceInset={{ vertical: 'never' }}>
<View style={styles.avatarContainer} testID='profile-view-avatar'>
<Avatar
text={username}
avatar={avatar && avatar.url}
size={100}
baseUrl={baseUrl}
2019-04-18 20:57:35 +00:00
userId={user.id}
token={user.token}
/>
</View>
<RCTextInput
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'
/>
<RCTextInput
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'
/>
<RCTextInput
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'
/>
<RCTextInput
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 (Object.keys(customFields).length) {
return this[Object.keys(customFields)[0]].focus();
}
this.avatarUrl.focus();
}}
secureTextEntry
testID='profile-view-new-password'
/>
{this.renderCustomFields()}
<RCTextInput
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'
/>
{this.renderAvatarButtons()}
<Button
title={I18n.t('Save_Changes')}
type='primary'
onPress={this.submit}
disabled={!this.formIsChanged()}
testID='profile-view-submit'
loading={saving}
/>
<Dialog.Container visible={showPasswordAlert}>
<Dialog.Title>
{I18n.t('Please_enter_your_password')}
</Dialog.Title>
<Dialog.Description>
{I18n.t('For_your_security_you_must_enter_your_current_password_to_continue')}
</Dialog.Description>
<Dialog.Input
onChangeText={value => this.setState({ currentPassword: value })}
secureTextEntry
testID='profile-view-typed-password'
style={styles.dialogInput}
/>
<Dialog.Button label={I18n.t('Cancel')} onPress={this.closePasswordAlert} />
<Dialog.Button label={I18n.t('Save')} onPress={this.submit} />
</Dialog.Container>
</SafeAreaView>
</ScrollView>
</KeyboardView>
2018-06-05 01:17:02 +00:00
);
}
}
const mapStateToProps = state => ({
user: {
id: state.login.user && state.login.user.id,
name: state.login.user && state.login.user.name,
username: state.login.user && state.login.user.username,
customFields: state.login.user && state.login.user.customFields,
emails: state.login.user && state.login.user.emails,
token: state.login.user && state.login.user.token
},
Accounts_CustomFields: state.settings.Accounts_CustomFields,
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
});
const mapDispatchToProps = dispatch => ({
setUser: params => dispatch(setUserAction(params))
});
export default connect(mapStateToProps, mapDispatchToProps)(ProfileView);