fixing small latency issue when uplading a temp profile image

This commit is contained in:
Blake Kaufman
2025-12-03 12:45:40 -05:00
parent e454c0957f
commit 4a2eccaae5
5 changed files with 117 additions and 135 deletions
@@ -512,28 +512,32 @@ function InnerContent({
},
]}
>
<ContactProfileImage
updated={
tempImage.shouldDelete
? null
: tempImage.uri
? tempImage.comparison?.updated
: isEditingMyProfile
? myProfileImage?.updated
: selectedAddedContactImage?.updated
}
uri={
tempImage.shouldDelete
? null
: tempImage.uri
? tempImage.comparison?.uri
: isEditingMyProfile
? myProfileImage?.localUri
: selectedAddedContactImage?.localUri
}
darkModeType={darkModeType}
theme={theme}
/>
{isAddingImage ? (
<FullLoadingScreen showText={false} />
) : (
<ContactProfileImage
updated={
tempImage.shouldDelete
? null
: tempImage.uri
? tempImage.comparison?.updated
: isEditingMyProfile
? myProfileImage?.updated
: selectedAddedContactImage?.updated
}
uri={
tempImage.shouldDelete
? null
: tempImage.uri
? tempImage.comparison?.uri
: isEditingMyProfile
? myProfileImage?.localUri
: selectedAddedContactImage?.localUri
}
darkModeType={darkModeType}
theme={theme}
/>
)}
</View>
{(isEditingMyProfile || selectedAddedContact.isLNURL) && (
<View style={styles.selectFromPhotos}>
@@ -576,7 +580,9 @@ function InnerContent({
inputs.name.length >= 30 ||
inputs.bio.length >= 150 ||
inputs.uniquename.length >= 30 ||
(selectedAddedContact?.isLNURL && inputs.receiveAddress.length >= 200)
(selectedAddedContact?.isLNURL &&
inputs.receiveAddress.length >= 200) ||
isAddingImage
)
return;
@@ -594,7 +600,7 @@ function InnerContent({
);
if (!areImagesTheSame) {
await saveProfileImage(
tempImage.uri,
tempImage,
isEditingMyProfile,
selectedAddedContact,
);
@@ -11,7 +11,6 @@ import ContactProfileImage from './internalComponents/profileImage';
import GetThemeColors from '../../../../hooks/themeColors';
import { useGlobalThemeContext } from '../../../../../context-store/theme';
import { useImageCache } from '../../../../../context-store/imageCache';
import { useProfileImage } from './hooks/useProfileImage';
import { useExpandedNavbar } from './hooks/useExpandedNavbar';
import FullLoadingScreen from '../../../../functions/CustomElements/loadingScreen';
import { Image } from 'expo-image';
@@ -19,73 +19,40 @@ export function useProfileImage() {
const [isAddingImage, setIsAddingImage] = useState(false);
/**
* Adds a profile picture for a contact
* @param {boolean} isEditingMyProfile - Whether editing own profile
* @param {object} selectedContact - The contact object (only needed if not editing own profile)
*/
const addProfilePicture = async (
isEditingMyProfile,
selectedContact = null,
) => {
const imagePickerResponse = await getImageFromLibrary({ quality: 1 });
const { didRun, error, imgURL } = imagePickerResponse;
if (!didRun) return;
if (error) {
navigate.navigate('ErrorScreen', { errorMessage: t(error) });
return;
}
if (isEditingMyProfile) {
const response = await uploadProfileImage({
imgURL: imgURL,
uuid: globalContactsInformation.myProfile.uuid,
});
if (!response) return;
toggleGlobalContactsInformation(
{
myProfile: {
...globalContactsInformation.myProfile,
hasProfileImage: true,
},
addedContacts: globalContactsInformation.addedContacts,
},
true,
);
return;
}
// For other contacts, just refresh cache
if (selectedContact) {
const savedImage = await resizeImage({ imgURL });
if (!savedImage.uri) return;
await refreshCache(selectedContact.uuid, savedImage.uri, false);
}
};
/**
* gets a profile picture for a contact
*/
const getProfileImage = async () => {
const imagePickerResponse = await getImageFromLibrary({ quality: 1 });
const { didRun, error, imgURL } = imagePickerResponse;
try {
const imagePickerResponse = await getImageFromLibrary({ quality: 1 });
const { didRun, error, imgURL } = imagePickerResponse;
if (!didRun) return;
if (!didRun) return;
if (error) {
navigate.navigate('ErrorScreen', { errorMessage: t(error) });
return;
if (error) {
navigate.navigate('ErrorScreen', { errorMessage: t(error) });
return;
}
const startTime = Date.now();
setIsAddingImage(true);
const savedImage = await resizeImage({ imgURL });
if (!savedImage.uri) return;
const offsetTime = Date.now() - startTime;
const remainingTime = Math.max(0, 700 - offsetTime);
if (remainingTime > 0) {
console.log(`Waiting ${remainingTime}ms to reach minimum 1s duration`);
await new Promise(resolve => setTimeout(resolve, remainingTime));
}
return { comparison: savedImage, imgURL };
} catch (err) {
console.log('error getting profile iamge', err);
} finally {
setIsAddingImage(false);
}
const savedImage = await resizeImage({ imgURL });
if (!savedImage.uri) return;
return { comparison: savedImage, imgURL };
};
/**
@@ -94,58 +61,85 @@ export function useProfileImage() {
* @param {boolean} isEditingMyProfile - Whether editing own profile
*/
const saveProfileImage = async (
imgURL,
imgData,
isEditingMyProfile,
selectedContact,
) => {
if (isEditingMyProfile) {
const response = await uploadProfileImage({
imgURL: imgURL,
uuid: globalContactsInformation.myProfile.uuid,
});
try {
if (isEditingMyProfile) {
const response = await uploadProfileImage({
imgURL: imgData.comparison.uri,
uuid: globalContactsInformation.myProfile.uuid,
});
if (!response) return;
if (!response) return;
toggleGlobalContactsInformation(
{
myProfile: {
...globalContactsInformation.myProfile,
hasProfileImage: true,
toggleGlobalContactsInformation(
{
myProfile: {
...globalContactsInformation.myProfile,
hasProfileImage: true,
},
addedContacts: globalContactsInformation.addedContacts,
},
addedContacts: globalContactsInformation.addedContacts,
},
true,
);
return;
}
true,
);
return;
}
// For other contacts, just refresh cache
if (selectedContact) {
const savedImage = await resizeImage({ imgURL });
if (!savedImage.uri) return;
await refreshCache(selectedContact.uuid, savedImage.uri, false);
// For other contacts, just refresh cache
if (selectedContact) {
await refreshCache(selectedContact.uuid, imgData.comparison.uri, false);
}
} catch (err) {
console.log('error saving profile image', err);
}
};
/**
* Resizes an image for consistancy
* Resizes and crops an image to a circle for profile pictures
* @param {object} params - Upload parameters
* @param {object} params.imgURL - Image URL object
*/
const resizeImage = async ({ imgURL }) => {
try {
const resized = ImageManipulator.ImageManipulator.manipulate(
const { width: originalWidth, height: originalHeight } = imgURL;
const photoWidth = originalWidth * 0.95;
const photoHeight = originalHeight * 0.95;
const targetSize = 250; // Match your largest display size
const smallerDimension = Math.min(photoWidth, photoHeight);
const cropSize = smallerDimension;
const cropX = (photoWidth - cropSize) / 2;
const cropY = (photoHeight - cropSize) / 2;
// Get image dimensions to calculate center crop
const manipulator = ImageManipulator.ImageManipulator.manipulate(
imgURL.uri,
).resize({ width: 350 });
);
const cropped = manipulator.crop({
originX: cropX,
originY: cropY,
width: cropSize,
height: cropSize,
});
const resized = cropped.resize({
width: targetSize,
height: targetSize,
});
const image = await resized.renderAsync();
const savedImage = await image.saveAsync({
compress: 0.4,
format: ImageManipulator.SaveFormat.WEBP,
});
return savedImage;
} catch (err) {
console.log('Error resizing image', err);
return {};
}
};
@@ -158,18 +152,11 @@ export function useProfileImage() {
*/
const uploadProfileImage = async ({ imgURL, uuid, removeImage }) => {
try {
setIsAddingImage(true);
if (!removeImage) {
const savedImage = await resizeImage({ imgURL });
if (!savedImage.uri)
throw new Error(t('contacts.editMyProfilePage.unableToSaveError'));
const response = await setDatabaseIMG(uuid, { uri: savedImage.uri });
const response = await setDatabaseIMG(uuid, { uri: imgURL });
if (response) {
await refreshCache(uuid, response, false);
await refreshCache(uuid, imgURL, false);
return true;
} else {
throw new Error(t('contacts.editMyProfilePage.unableToSaveError'));
@@ -183,8 +170,6 @@ export function useProfileImage() {
console.log(err);
navigate.navigate('ErrorScreen', { errorMessage: err.message });
return false;
} finally {
setIsAddingImage(false);
}
};
@@ -232,7 +217,6 @@ export function useProfileImage() {
return {
isAddingImage,
addProfilePicture,
deleteProfilePicture,
getProfileImage,
saveProfileImage,
-1
View File
@@ -23,7 +23,6 @@ import { useGlobalContextProvider } from '../../../context-store/context';
import openWebBrowser from '../../functions/openWebBrowser';
import { useTranslation } from 'react-i18next';
import GetThemeColors from '../../hooks/themeColors';
import { useProfileImage } from '../../components/admin/homeComponents/contacts/hooks/useProfileImage';
import { useImageCache } from '../../../context-store/imageCache';
import FullLoadingScreen from '../../functions/CustomElements/loadingScreen';
import ContactProfileImage from '../../components/admin/homeComponents/contacts/internalComponents/profileImage';
+4 -10
View File
@@ -1,11 +1,6 @@
import {
getDownloadURL,
putFile,
ref,
deleteObject,
} from '@react-native-firebase/storage';
import {BLITZ_PROFILE_IMG_STORAGE_REF} from '../app/constants';
import {storage} from './initializeFirebase';
import { putFile, ref, deleteObject } from '@react-native-firebase/storage';
import { BLITZ_PROFILE_IMG_STORAGE_REF } from '../app/constants';
import { storage } from './initializeFirebase';
export async function setDatabaseIMG(publicKey, imgURL) {
try {
@@ -16,8 +11,7 @@ export async function setDatabaseIMG(publicKey, imgURL) {
await putFile(reference, imgURL.uri);
const downloadURL = await getDownloadURL(reference);
return downloadURL;
return true;
} catch (err) {
console.log('set database image error', err);
return false;