浏览代码

avatar upload fix

Viktoriia 7 月之前
父节点
当前提交
4392df4087

+ 10 - 3
src/modules/api/user/user-api.tsx

@@ -358,9 +358,16 @@ export const userApi = {
 
     formData.append('token', data.token);
     formData.append('user', JSON.stringify(data.user));
-    formData.append('photo', {
-      ...data.photo
-    } as unknown as Blob);
+    if (data.photo && data.photo?.uri) {
+      formData.append('photo', {
+        type:
+          data.photo.type === 'image'
+            ? data.photo.type + '/' + data.photo.uri.split('.').pop()!
+            : data.photo.type,
+        uri: data.photo.uri,
+        name: data.photo.name
+      } as unknown as Blob);
+    }
 
     return request.postForm<PostSetProfileDataReturn>(API.SET_USER_SETTINGS_DATA, formData);
   },

+ 3 - 1
src/screens/InAppScreens/MapScreen/index.tsx

@@ -80,6 +80,7 @@ import SeriesIcon from 'assets/icons/travels-section/series.svg';
 import NomadsIcon from 'assets/icons/bottom-navigation/travellers.svg';
 import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
 import MapButton from 'src/components/MapButton';
+import { useAvatarStore } from 'src/stores/avatarVersionStore';
 
 const defaultUserAvatar = require('assets/icon-user-share-location-solid.png');
 const logo = require('assets/logo-ua.png');
@@ -267,6 +268,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
 
   const [isConnected, setIsConnected] = useState<boolean>(true);
   const netInfo = useConnection();
+  const { avatarVersion } = useAvatarStore();
 
   const { data: isFeatureActive } = usePostIsFeatureActiveQuery(token, !!token && isConnected);
   const { data: regionsList } = useGetListRegionsQuery(isConnected);
@@ -1537,7 +1539,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
                 userInfoData?.avatar ? (
                   <Image
                     style={styles.avatar}
-                    source={{ uri: API_HOST + '/img/avatars/' + userInfoData?.avatar }}
+                    source={{ uri: API_HOST + '/img/avatars/' + userInfoData?.avatar + '?v=' + avatarVersion }}
                   />
                 ) : (
                   <AvatarWithInitials

+ 13 - 3
src/screens/InAppScreens/ProfileScreen/Profile/edit-personal-info.tsx

@@ -45,6 +45,7 @@ import { NAVIGATION_PAGES } from 'src/types';
 import { useDeleteUserMutation } from '@api/app';
 import { useNotification } from 'src/contexts/NotificationContext';
 import { useMessagesStore } from 'src/stores/unreadMessagesStore';
+import { useAvatarStore } from 'src/stores/avatarVersionStore';
 
 const ProfileSchema = yup.object({
   username: yup.string().optional(),
@@ -76,7 +77,8 @@ export const EditPersonalInfo = () => {
   const { data, error } = usePostGetProfileQuery(String(token), true);
   const { updateNotificationStatus } = useNotification();
   const updateUnreadMessagesCount = useMessagesStore((state) => state.updateUnreadMessagesCount);
-
+  const [isSubmitting, setIsSubmitting] = useState(false);
+  const {incrementAvatarVersion} = useAvatarStore();
 
   const regions = useGetRegionsWithFlagQuery(true);
   const [modalInfo, setModalInfo] = useState({
@@ -153,6 +155,8 @@ export const EditPersonalInfo = () => {
               }
             }}
             onSubmit={async (values) => {
+              setIsSubmitting(true);
+
               const profileData: PostSetProfileData = {
                 token: String(token),
                 user: {
@@ -184,7 +188,7 @@ export const EditPersonalInfo = () => {
                 };
               }
 
-              updateProfile(profileData, {
+              await updateProfile(profileData, {
                 onSuccess: () => {
                   queryClient.invalidateQueries({
                     queryKey: userQueryKeys.getProfileData(),
@@ -198,7 +202,13 @@ export const EditPersonalInfo = () => {
                   Image.clearDiskCache();
                   Image.clearMemoryCache();
 
+                  incrementAvatarVersion();
+
+                  setIsSubmitting(false);
                   navigation.goBack();
+                },
+                onError: () => {
+                  setIsSubmitting(false);
                 }
               });
             }}
@@ -333,7 +343,7 @@ export const EditPersonalInfo = () => {
                   formikError={props.touched.other && props.errors.other}
                 />
                 <View style={{ marginTop: 15, marginBottom: 15, gap: 8 }}>
-                  <Button onPress={props.handleSubmit}>Save</Button>
+                  <Button onPress={props.handleSubmit} disabled={isSubmitting}>Save</Button>
                   <Button
                     variant={ButtonVariants.OPACITY}
                     containerStyles={{ backgroundColor: Colors.WHITE, borderColor: Colors.RED }}

+ 8 - 2
src/screens/InAppScreens/ProfileScreen/index.tsx

@@ -44,6 +44,7 @@ import UnauthenticatedProfileScreen from './UnauthenticatedProfileScreen';
 import { PersonalInfo } from './Components/PersonalInfo';
 import { usePostUpdateFriendStatusMutation } from '@api/friends';
 import Tooltip from 'react-native-walkthrough-tooltip';
+import { useAvatarStore } from 'src/stores/avatarVersionStore';
 
 type Props = {
   navigation: NavigationProp<any>;
@@ -77,6 +78,7 @@ const ProfileScreen: FC<Props> = ({ navigation, route }) => {
   });
   const [tooltipVisible, setTooltipVisible] = useState(false);
   const [fullSizeImageVisible, setFullSizeImageVisible] = useState(false);
+  const { avatarVersion } = useAvatarStore();
 
   useFocusEffect(
     useCallback(() => {
@@ -256,7 +258,9 @@ const ProfileScreen: FC<Props> = ({ navigation, route }) => {
               >
                 <Image
                   style={styles.avatar}
-                  source={{ uri: API_HOST + '/img/avatars/' + data.user_data.avatar }}
+                  source={{
+                    uri: API_HOST + '/img/avatars/' + data.user_data.avatar + '?v=' + avatarVersion
+                  }}
                 />
               </TouchableOpacity>
             ) : (
@@ -477,7 +481,9 @@ const ProfileScreen: FC<Props> = ({ navigation, route }) => {
         title=""
       />
       <ImageView
-        images={[{ uri: API_HOST + '/img/avatars/' + data.user_data.avatar }]}
+        images={[
+          { uri: API_HOST + '/img/avatars/' + data.user_data.avatar + '?v=' + avatarVersion }
+        ]}
         keyExtractor={(imageSrc, index) => index.toString()}
         imageIndex={0}
         visible={fullSizeImageVisible}

+ 11 - 0
src/stores/avatarVersionStore.ts

@@ -0,0 +1,11 @@
+import { create } from 'zustand';
+
+interface AvatarState {
+  avatarVersion: number;
+  incrementAvatarVersion: () => void;
+}
+
+export const useAvatarStore = create<AvatarState>((set) => ({
+  avatarVersion: 0,
+  incrementAvatarVersion: () => set((state) => ({ avatarVersion: state.avatarVersion + 1 }))
+}));