types for change avatar view context
This commit is contained in:
parent
0ea494e3e7
commit
fe35747b52
|
@ -0,0 +1 @@
|
||||||
|
export type TChangeAvatarViewContext = 'profile' | 'room';
|
|
@ -1,6 +1,7 @@
|
||||||
// Fast Image can't render a svg image from a uri yet, because of that we aren't test the svg within the RegEx
|
// Fast Image can't render a svg image from a uri yet, because of that we aren't test the svg within the RegEx
|
||||||
const regExpUrlImage = new RegExp(
|
const regExpUrlImage = new RegExp(
|
||||||
'.(jpg|jpeg|png|webp|avif|gif)' + // type of the URL
|
'.(jpg|jpeg|png|webp|avif|gif|tiff)' + // type of the URL
|
||||||
'(\\?[;&a-z\\d%_.~+=-]*)?' // query string
|
'(\\?[;&a-z\\d%_.~+=-]*)?',
|
||||||
|
'i' // query string
|
||||||
);
|
);
|
||||||
export const isImage = (url: string) => regExpUrlImage.test(url);
|
export const isImage = (url: string) => regExpUrlImage.test(url);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { IMessage } from '../../definitions/IMessage';
|
||||||
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../../definitions/ISubscription';
|
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../../definitions/ISubscription';
|
||||||
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
|
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
|
||||||
import { ILivechatTag } from '../../definitions/ILivechatTag';
|
import { ILivechatTag } from '../../definitions/ILivechatTag';
|
||||||
|
import { TChangeAvatarViewContext } from '../../definitions/TChangeAvatarViewContext';
|
||||||
|
|
||||||
export type MasterDetailChatsStackParamList = {
|
export type MasterDetailChatsStackParamList = {
|
||||||
RoomView: {
|
RoomView: {
|
||||||
|
@ -59,7 +60,7 @@ export type ModalStackParamList = {
|
||||||
isRadio?: boolean;
|
isRadio?: boolean;
|
||||||
};
|
};
|
||||||
ChangeAvatarView: {
|
ChangeAvatarView: {
|
||||||
fromUser?: boolean;
|
context: TChangeAvatarViewContext;
|
||||||
titleHeader?: string;
|
titleHeader?: string;
|
||||||
room?: ISubscription;
|
room?: ISubscription;
|
||||||
t?: SubscriptionType;
|
t?: SubscriptionType;
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { ModalStackParamList } from './MasterDetailStack/types';
|
||||||
import { TThreadModel } from '../definitions';
|
import { TThreadModel } from '../definitions';
|
||||||
import { ILivechatDepartment } from '../definitions/ILivechatDepartment';
|
import { ILivechatDepartment } from '../definitions/ILivechatDepartment';
|
||||||
import { ILivechatTag } from '../definitions/ILivechatTag';
|
import { ILivechatTag } from '../definitions/ILivechatTag';
|
||||||
|
import { TChangeAvatarViewContext } from '../definitions/TChangeAvatarViewContext';
|
||||||
|
|
||||||
export type ChatsStackParamList = {
|
export type ChatsStackParamList = {
|
||||||
ModalStackNavigator: NavigatorScreenParams<ModalStackParamList>;
|
ModalStackNavigator: NavigatorScreenParams<ModalStackParamList>;
|
||||||
|
@ -181,7 +182,7 @@ export type ChatsStackParamList = {
|
||||||
videoConf?: boolean;
|
videoConf?: boolean;
|
||||||
};
|
};
|
||||||
ChangeAvatarView: {
|
ChangeAvatarView: {
|
||||||
fromUser?: boolean;
|
context: TChangeAvatarViewContext;
|
||||||
titleHeader?: string;
|
titleHeader?: string;
|
||||||
room?: ISubscription;
|
room?: ISubscription;
|
||||||
t?: SubscriptionType;
|
t?: SubscriptionType;
|
||||||
|
@ -201,7 +202,7 @@ export type ProfileStackParamList = {
|
||||||
onChangeValue: Function;
|
onChangeValue: Function;
|
||||||
};
|
};
|
||||||
ChangeAvatarView: {
|
ChangeAvatarView: {
|
||||||
fromUser?: boolean;
|
context: TChangeAvatarViewContext;
|
||||||
titleHeader?: string;
|
titleHeader?: string;
|
||||||
room?: ISubscription;
|
room?: ISubscription;
|
||||||
t?: SubscriptionType;
|
t?: SubscriptionType;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
import { IAvatar, IUser } from '../../definitions';
|
import { IAvatar } from '../../definitions';
|
||||||
import { Services } from '../../lib/services';
|
import { Services } from '../../lib/services';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -10,11 +10,11 @@ import AvatarSuggestionItem from './AvatarSuggestionItem';
|
||||||
|
|
||||||
const AvatarSuggestion = ({
|
const AvatarSuggestion = ({
|
||||||
onPress,
|
onPress,
|
||||||
user,
|
username,
|
||||||
resetAvatar
|
resetAvatar
|
||||||
}: {
|
}: {
|
||||||
onPress: (value: IAvatar | null) => void;
|
onPress: (value: IAvatar | null) => void;
|
||||||
user?: IUser;
|
username?: string;
|
||||||
resetAvatar?: () => void;
|
resetAvatar?: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [avatarSuggestions, setAvatarSuggestions] = useState<IAvatar[]>([]);
|
const [avatarSuggestions, setAvatarSuggestions] = useState<IAvatar[]>([]);
|
||||||
|
@ -40,11 +40,11 @@ const AvatarSuggestion = ({
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1 }}>
|
<View style={styles.containerImagesUploaded}>
|
||||||
<Text style={[styles.itemLabel, { color: colors.titleText }]}>{I18n.t('Images_uploaded')}</Text>
|
<Text style={[styles.itemLabel, { color: colors.titleText }]}>{I18n.t('Images_uploaded')}</Text>
|
||||||
<View style={styles.containerAvatarSuggestion}>
|
<View style={styles.containerAvatarSuggestion}>
|
||||||
{user?.username && resetAvatar ? (
|
{username && resetAvatar ? (
|
||||||
<AvatarSuggestionItem text={`@${user.username}`} testID={`reset-avatar-suggestion`} onPress={resetAvatar} />
|
<AvatarSuggestionItem text={`@${username}`} testID={`reset-avatar-suggestion`} onPress={resetAvatar} />
|
||||||
) : null}
|
) : null}
|
||||||
{avatarSuggestions.slice(0, 7).map(item => (
|
{avatarSuggestions.slice(0, 7).map(item => (
|
||||||
<AvatarSuggestionItem item={item} testID={`${item?.service}-avatar-suggestion`} onPress={onPress} />
|
<AvatarSuggestionItem item={item} testID={`${item?.service}-avatar-suggestion`} onPress={onPress} />
|
||||||
|
|
|
@ -32,8 +32,9 @@ const ChangeAvatarView = () => {
|
||||||
const [textAvatar, setTextAvatar] = useState('');
|
const [textAvatar, setTextAvatar] = useState('');
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const { user, serverVersion } = useAppSelector(state => ({
|
const { userId, username, serverVersion } = useAppSelector(state => ({
|
||||||
user: getUserSelector(state),
|
userId: getUserSelector(state).id,
|
||||||
|
username: getUserSelector(state).username,
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
serverVersion: state.server.version
|
serverVersion: state.server.version
|
||||||
}));
|
}));
|
||||||
|
@ -41,7 +42,7 @@ const ChangeAvatarView = () => {
|
||||||
const avatarUrl = useRef<string | undefined>('');
|
const avatarUrl = useRef<string | undefined>('');
|
||||||
|
|
||||||
const navigation = useNavigation<StackNavigationProp<ChatsStackParamList, 'ChangeAvatarView'>>();
|
const navigation = useNavigation<StackNavigationProp<ChatsStackParamList, 'ChangeAvatarView'>>();
|
||||||
const { fromUser, titleHeader, room, t } = useRoute<RouteProp<ChatsStackParamList, 'ChangeAvatarView'>>().params;
|
const { context, titleHeader, room, t } = useRoute<RouteProp<ChatsStackParamList, 'ChangeAvatarView'>>().params;
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
|
@ -75,7 +76,7 @@ const ChangeAvatarView = () => {
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
let result;
|
let result;
|
||||||
if (!fromUser && room?.rid) {
|
if ((context === 'room') && room?.rid) {
|
||||||
// Change Rooms Avatar
|
// Change Rooms Avatar
|
||||||
result = await changeRoomsAvatar(room.rid);
|
result = await changeRoomsAvatar(room.rid);
|
||||||
} else if (avatar?.url) {
|
} else if (avatar?.url) {
|
||||||
|
@ -118,7 +119,7 @@ const ChangeAvatarView = () => {
|
||||||
|
|
||||||
const resetUserAvatar = async () => {
|
const resetUserAvatar = async () => {
|
||||||
try {
|
try {
|
||||||
await Services.resetAvatar(user.id);
|
await Services.resetAvatar(userId);
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return handleError(e, 'setAvatarFromService', 'changing_avatar');
|
return handleError(e, 'setAvatarFromService', 'changing_avatar');
|
||||||
|
@ -137,8 +138,8 @@ const ChangeAvatarView = () => {
|
||||||
|
|
||||||
const resetAvatar = () => {
|
const resetAvatar = () => {
|
||||||
setAvatar(null);
|
setAvatar(null);
|
||||||
setTextAvatar(`@${user.username}`);
|
setTextAvatar(`@${username}`);
|
||||||
avatarUrl.current = `@${user.username}`;
|
avatarUrl.current = `@${username}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetRoomAvatar = () => {
|
const resetRoomAvatar = () => {
|
||||||
|
@ -181,7 +182,7 @@ const ChangeAvatarView = () => {
|
||||||
>
|
>
|
||||||
<View style={styles.avatarContainer} testID='change-avatar-view-avatar'>
|
<View style={styles.avatarContainer} testID='change-avatar-view-avatar'>
|
||||||
<Avatar
|
<Avatar
|
||||||
text={room?.name || textAvatar || user.username}
|
text={room?.name || textAvatar || username}
|
||||||
avatar={avatar?.url}
|
avatar={avatar?.url}
|
||||||
isStatic={avatar?.url}
|
isStatic={avatar?.url}
|
||||||
size={100}
|
size={100}
|
||||||
|
@ -189,9 +190,9 @@ const ChangeAvatarView = () => {
|
||||||
{...ridProps}
|
{...ridProps}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{fromUser ? <AvatarUrl submit={value => setAvatar({ url: value, data: value, service: 'url' })} /> : null}
|
{context=== 'profile' ? <AvatarUrl submit={value => setAvatar({ url: value, data: value, service: 'url' })} /> : null}
|
||||||
<List.Separator style={styles.separator} />
|
<List.Separator style={styles.separator} />
|
||||||
{fromUser ? <AvatarSuggestion resetAvatar={resetAvatar} user={user} onPress={setAvatar} /> : null}
|
{context=== 'profile' ? <AvatarSuggestion resetAvatar={resetAvatar} username={username} onPress={setAvatar} /> : null}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
title={I18n.t('Upload_image')}
|
title={I18n.t('Upload_image')}
|
||||||
|
@ -201,7 +202,7 @@ const ChangeAvatarView = () => {
|
||||||
onPress={pickImage}
|
onPress={pickImage}
|
||||||
testID='change-avatar-view-logout-other-locations'
|
testID='change-avatar-view-logout-other-locations'
|
||||||
/>
|
/>
|
||||||
{!fromUser && serverVersion && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '3.6.0') ? (
|
{context === 'room' && serverVersion && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '3.6.0') ? (
|
||||||
<Button
|
<Button
|
||||||
title={I18n.t('Delete_image')}
|
title={I18n.t('Delete_image')}
|
||||||
type='primary'
|
type='primary'
|
||||||
|
|
|
@ -3,9 +3,6 @@ import { StyleSheet } from 'react-native';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
|
|
||||||
export default StyleSheet.create({
|
export default StyleSheet.create({
|
||||||
disabled: {
|
|
||||||
opacity: 0.3
|
|
||||||
},
|
|
||||||
avatarContainer: {
|
avatarContainer: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
@ -19,6 +16,9 @@ export default StyleSheet.create({
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
...sharedStyles.textSemibold
|
...sharedStyles.textSemibold
|
||||||
},
|
},
|
||||||
|
containerImagesUploaded: {
|
||||||
|
flex: 1
|
||||||
|
},
|
||||||
containerAvatarSuggestion: {
|
containerAvatarSuggestion: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
|
|
|
@ -287,7 +287,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
|
|
||||||
handleEditAvatar = () => {
|
handleEditAvatar = () => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
navigation.navigate('ChangeAvatarView', { fromUser: true });
|
navigation.navigate('ChangeAvatarView', { context: 'profile' });
|
||||||
};
|
};
|
||||||
|
|
||||||
renderAvatarButton = ({ key, child, onPress, disabled = false }: IAvatarButton) => {
|
renderAvatarButton = ({ key, child, onPress, disabled = false }: IAvatarButton) => {
|
||||||
|
|
|
@ -465,7 +465,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
|
||||||
handleEditAvatar = () => {
|
handleEditAvatar = () => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
navigation.navigate('ChangeAvatarView', { titleHeader: I18n.t('Room_Info'), room, t: room.t });
|
navigation.navigate('ChangeAvatarView', { titleHeader: I18n.t('Room_Info'), room, t: room.t, context: 'room' });
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleRoomType = (value: boolean) => {
|
toggleRoomType = (value: boolean) => {
|
||||||
|
|
|
@ -403,7 +403,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
|
||||||
handleEditAvatar = () => {
|
handleEditAvatar = () => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
navigation.navigate('ChangeAvatarView', { titleHeader: I18n.t('Room_Info'), room, t: this.t });
|
navigation.navigate('ChangeAvatarView', { titleHeader: I18n.t('Room_Info'), room, t: this.t, context: 'room' });
|
||||||
};
|
};
|
||||||
|
|
||||||
renderAvatar = (room: ISubscription, roomUser: IUserParsed) => {
|
renderAvatar = (room: ISubscription, roomUser: IUserParsed) => {
|
||||||
|
|
Loading…
Reference in New Issue