[NEW] Change Avatar View
This commit is contained in:
parent
a2722f07b0
commit
49f2c28b3e
|
@ -3,11 +3,15 @@ import React, { useEffect, useRef, useState } from 'react';
|
|||
import { shallowEqual, useSelector } from 'react-redux';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import Button from '../Button';
|
||||
import { IApplicationState, TSubscriptionModel, TUserModel } from '../../definitions';
|
||||
import database from '../../lib/database';
|
||||
import { getUserSelector } from '../../selectors/login';
|
||||
import Avatar from './Avatar';
|
||||
import { IAvatar } from './interfaces';
|
||||
import I18n from '../../i18n';
|
||||
import { useTheme } from '../../theme';
|
||||
import styles from './styles';
|
||||
|
||||
const AvatarContainer = ({
|
||||
style,
|
||||
|
@ -21,10 +25,12 @@ const AvatarContainer = ({
|
|||
onPress,
|
||||
getCustomEmoji,
|
||||
isStatic,
|
||||
rid
|
||||
}: IAvatar): React.ReactElement => {
|
||||
rid,
|
||||
handleEdit
|
||||
}: IAvatar & { handleEdit?: () => void }): React.ReactElement => {
|
||||
const subscription = useRef<Subscription>();
|
||||
const [avatarETag, setAvatarETag] = useState<string | undefined>('');
|
||||
const { colors } = useTheme();
|
||||
|
||||
const isDirect = () => type === 'd';
|
||||
|
||||
|
@ -85,27 +91,39 @@ const AvatarContainer = ({
|
|||
}, [text, type, size, avatarETag, externalProviderUrl]);
|
||||
|
||||
return (
|
||||
<Avatar
|
||||
server={server}
|
||||
style={style}
|
||||
text={text}
|
||||
avatar={avatar}
|
||||
emoji={emoji}
|
||||
size={size}
|
||||
borderRadius={borderRadius}
|
||||
type={type}
|
||||
children={children}
|
||||
userId={id}
|
||||
token={token}
|
||||
onPress={onPress}
|
||||
getCustomEmoji={getCustomEmoji}
|
||||
isStatic={isStatic}
|
||||
rid={rid}
|
||||
blockUnauthenticatedAccess={blockUnauthenticatedAccess}
|
||||
externalProviderUrl={externalProviderUrl}
|
||||
avatarETag={avatarETag}
|
||||
serverVersion={serverVersion}
|
||||
/>
|
||||
<>
|
||||
<Avatar
|
||||
server={server}
|
||||
style={style}
|
||||
text={text}
|
||||
avatar={avatar}
|
||||
emoji={emoji}
|
||||
size={size}
|
||||
borderRadius={borderRadius}
|
||||
type={type}
|
||||
children={children}
|
||||
userId={id}
|
||||
token={token}
|
||||
onPress={onPress}
|
||||
getCustomEmoji={getCustomEmoji}
|
||||
isStatic={isStatic}
|
||||
rid={rid}
|
||||
blockUnauthenticatedAccess={blockUnauthenticatedAccess}
|
||||
externalProviderUrl={externalProviderUrl}
|
||||
avatarETag={avatarETag}
|
||||
serverVersion={serverVersion}
|
||||
/>
|
||||
{handleEdit ? (
|
||||
<Button
|
||||
title={I18n.t('Edit')}
|
||||
type='secondary'
|
||||
backgroundColor={colors.passcodeButtonActive}
|
||||
onPress={handleEdit}
|
||||
testID='avatar-edit-button'
|
||||
style={styles.editAvatarButton}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
export default StyleSheet.create({
|
||||
editAvatarButton: {
|
||||
marginTop: 8,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 12
|
||||
}
|
||||
});
|
|
@ -876,5 +876,7 @@
|
|||
"Call": "Call",
|
||||
"Reply_in_direct_message": "Reply in Direct Message",
|
||||
"room_archived": "archived room",
|
||||
"room_unarchived": "unarchived room"
|
||||
"room_unarchived": "unarchived room",
|
||||
"Upload_image": "Upload image",
|
||||
"Delete_image": "Delete image"
|
||||
}
|
|
@ -68,6 +68,7 @@ import AddChannelTeamView from '../views/AddChannelTeamView';
|
|||
import AddExistingChannelView from '../views/AddExistingChannelView';
|
||||
import SelectListView from '../views/SelectListView';
|
||||
import DiscussionsView from '../views/DiscussionsView';
|
||||
import ChangeAvatarView from '../views/ChangeAvatarView';
|
||||
import {
|
||||
AdminPanelStackParamList,
|
||||
ChatsStackParamList,
|
||||
|
@ -96,6 +97,7 @@ const ChatsStackNavigator = () => {
|
|||
<ChatsStack.Screen name='SelectListView' component={SelectListView} options={SelectListView.navigationOptions} />
|
||||
<ChatsStack.Screen name='RoomInfoView' component={RoomInfoView} options={RoomInfoView.navigationOptions} />
|
||||
<ChatsStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
|
||||
<ProfileStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
|
||||
<ChatsStack.Screen name='RoomMembersView' component={RoomMembersView} />
|
||||
<ChatsStack.Screen name='DiscussionsView' component={DiscussionsView} />
|
||||
<ChatsStack.Screen
|
||||
|
@ -155,6 +157,7 @@ const ProfileStackNavigator = () => {
|
|||
>
|
||||
<ProfileStack.Screen name='ProfileView' component={ProfileView} options={ProfileView.navigationOptions} />
|
||||
<ProfileStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
|
||||
<ProfileStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
|
||||
<ProfileStack.Screen name='UserNotificationPrefView' component={UserNotificationPrefView} />
|
||||
<ProfileStack.Screen name='PickerView' component={PickerView} options={PickerView.navigationOptions} />
|
||||
</ProfileStack.Navigator>
|
||||
|
|
|
@ -180,6 +180,10 @@ export type ChatsStackParamList = {
|
|||
onlyAudio?: boolean;
|
||||
videoConf?: boolean;
|
||||
};
|
||||
ChangeAvatarView: {
|
||||
fromUser?: boolean;
|
||||
titleHeader?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type ProfileStackParamList = {
|
||||
|
@ -194,6 +198,10 @@ export type ProfileStackParamList = {
|
|||
goBack?: Function;
|
||||
onChangeValue: Function;
|
||||
};
|
||||
ChangeAvatarView: {
|
||||
fromUser?: boolean;
|
||||
titleHeader?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type SettingsStackParamList = {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import React, { useState } from 'react';
|
||||
|
||||
import I18n from '../../i18n';
|
||||
import { FormTextInput } from '../../containers/TextInput';
|
||||
|
||||
const AvatarUrl = ({ onSubmit }: { onSubmit: (value: string) => void }) => {
|
||||
const [avatarUrl, setAvatarUrl] = useState('');
|
||||
return (
|
||||
<FormTextInput
|
||||
label={I18n.t('Avatar_Url')}
|
||||
placeholder={I18n.t('Avatar_Url')}
|
||||
value={avatarUrl || undefined}
|
||||
onChangeText={setAvatarUrl}
|
||||
onSubmitEditing={() => onSubmit(avatarUrl)}
|
||||
testID='change-avatar-view-avatar-url'
|
||||
containerStyle={{ marginBottom: 0 }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default AvatarUrl;
|
|
@ -0,0 +1,72 @@
|
|||
import React, { useState } from 'react';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
|
||||
import KeyboardView from '../../containers/KeyboardView';
|
||||
import sharedStyles from '../Styles';
|
||||
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import { useTheme } from '../../theme';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
import * as List from '../../containers/List';
|
||||
import styles from './styles';
|
||||
import { useAppSelector } from '../../lib/hooks';
|
||||
import { getUserSelector } from '../../selectors/login';
|
||||
import Avatar from '../../containers/Avatar';
|
||||
import AvatarUrl from './AvatarUrl';
|
||||
import Button from '../../containers/Button';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
const ChangeAvatarView = () => {
|
||||
const [avatarUrl, setAvatarUrl] = useState('');
|
||||
const { colors } = useTheme();
|
||||
|
||||
const user = useAppSelector(state => getUserSelector(state));
|
||||
|
||||
return (
|
||||
<KeyboardView
|
||||
style={{ backgroundColor: colors.auxiliaryBackground }}
|
||||
contentContainerStyle={sharedStyles.container}
|
||||
keyboardVerticalOffset={128}
|
||||
>
|
||||
<StatusBar />
|
||||
<SafeAreaView testID='change-avatar-view'>
|
||||
<ScrollView
|
||||
contentContainerStyle={sharedStyles.containerScrollView}
|
||||
testID='change-avatar-view-list'
|
||||
{...scrollPersistTaps}
|
||||
>
|
||||
<View style={styles.avatarContainer} testID='change-avatar-view-avatar'>
|
||||
<Avatar text={user.username} avatar={avatarUrl} isStatic={avatarUrl} size={100} />
|
||||
</View>
|
||||
<AvatarUrl onSubmit={(value: string) => setAvatarUrl(value)} />
|
||||
<List.Separator style={styles.separator} />
|
||||
|
||||
<Button
|
||||
title={I18n.t('Upload_image')}
|
||||
type='secondary'
|
||||
backgroundColor={colors.chatComponentBackground}
|
||||
onPress={() => {}}
|
||||
testID='change-avatar-view-logout-other-locations'
|
||||
/>
|
||||
<Button
|
||||
title={I18n.t('Delete_image')}
|
||||
type='primary'
|
||||
backgroundColor={colors.dangerColor}
|
||||
onPress={() => {}}
|
||||
testID='change-avatar-view-delete-my-account'
|
||||
/>
|
||||
<Button
|
||||
title={I18n.t('Save')}
|
||||
type='primary'
|
||||
onPress={() => {}}
|
||||
// disabled={!this.formIsChanged()}
|
||||
testID='change-avatar-view-submit'
|
||||
// loading={saving}
|
||||
/>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</KeyboardView>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChangeAvatarView;
|
|
@ -0,0 +1,15 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
export default StyleSheet.create({
|
||||
disabled: {
|
||||
opacity: 0.3
|
||||
},
|
||||
avatarContainer: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 32
|
||||
},
|
||||
separator: {
|
||||
marginVertical: 16
|
||||
}
|
||||
});
|
|
@ -369,6 +369,11 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
this.setAvatar({ url: avatarUrl, data: avatarUrl, service: 'url' });
|
||||
};
|
||||
|
||||
handleEditAvatar = () => {
|
||||
const { navigation } = this.props;
|
||||
navigation.navigate('ChangeAvatarView', { fromUser: true });
|
||||
};
|
||||
|
||||
renderAvatarButton = ({ key, child, onPress, disabled = false }: IAvatarButton) => {
|
||||
const { theme } = this.props;
|
||||
return (
|
||||
|
@ -543,7 +548,13 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
|||
<SafeAreaView testID='profile-view'>
|
||||
<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} />
|
||||
<Avatar
|
||||
text={user.username}
|
||||
avatar={avatar?.url}
|
||||
isStatic={avatar?.url}
|
||||
size={100}
|
||||
handleEdit={Accounts_AllowUserAvatarChange ? this.handleEditAvatar : undefined}
|
||||
/>
|
||||
</View>
|
||||
<FormTextInput
|
||||
editable={Accounts_AllowRealNameChange}
|
||||
|
|
|
@ -7,7 +7,7 @@ export default StyleSheet.create({
|
|||
avatarContainer: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 10
|
||||
marginBottom: 24
|
||||
},
|
||||
avatarButtons: {
|
||||
flexWrap: 'wrap',
|
||||
|
|
Loading…
Reference in New Issue