import { useState, useEffect } from 'react' import { supabase } from '@/lib/supabase' import { StyleSheet, Alert, Image, TouchableOpacity } from 'react-native' import * as ImagePicker from 'expo-image-picker' //import { ImageManipulator } from 'expo-image-manipulator'; import { ThemedView, ThemedText, ThemedTextButton } from '../theme'; import { IconSymbol } from '@/components/ui/IconSymbol'; interface Props { size: number url: string | null onUpload: (filePath: string) => void } export default function Avatar({ url, size = 150, onUpload }: Props) { const [uploading, setUploading] = useState(false) const [avatarUrl, setAvatarUrl] = useState(null) const avatarSize = { height: size, width: size } useEffect(() => { if (url) downloadImage(url) }, [url]) async function downloadImage(path: string) { try { const { data, error } = await supabase.storage.from('avatars').download(path) if (error) { throw error } const fr = new FileReader() fr.readAsDataURL(data) fr.onload = () => { setAvatarUrl(fr.result as string) } } catch (error) { if (error instanceof Error) { console.log('Error downloading image: ', error.message) } } }; async function uploadAvatar() { try { setUploading(true) const { data: { user } } = await supabase.auth.getUser(); const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, // Restrict to only images allowsMultipleSelection: false, // Can only select one image allowsEditing: true, // Allows the user to crop / rotate their photo before uploading it quality: 1, exif: false, // We don't want nor need that data. }); if (result.canceled || !result.assets || result.assets.length === 0) { console.log('User cancelled image picker.'); return; } //const manipulatedImage = await ImageManipulator.manipulate(result.assets[0].uri) //.resize({ width: 300 }) //.renderAsync(); //const manipulateResult = await manipulateAsync( //result.assets[0].uri, //[{resize: {width: 300, height: 300}}], //{compress: 0.7, format: SaveFormat.JPEG} //); const image = result.assets[0]; console.log('Got image', image) if (!image.uri) { throw new Error('No image uri!') // Realistically, this should never happen, but just in case... } const arraybuffer = await fetch(image.uri).then((res) => res.arrayBuffer()) const fileExt = image.uri?.split('.').pop()?.toLowerCase() ?? 'jpeg' const path = `${Date.now()}.${fileExt}` const { data, error: uploadError } = await supabase.storage .from('avatars') .upload(path, arraybuffer, { contentType: image.mimeType ?? 'image/jpeg', }); const { data: updateData, error: updateError } = await supabase .from('profiles') .update({ avatar_url: data?.path }) .eq('id', user?.id); if (uploadError) { throw uploadError } onUpload(data.path) } catch (error) { if (error instanceof Error) { Alert.alert(error.message) } else { throw error } } finally { setUploading(false) } }; return ( {avatarUrl ? ( ) : ( )} Change Photo ); } const styles = StyleSheet.create({ avatarContainer: { alignItems: 'center', marginTop: 20, marginBottom: 30, }, avatar: { width: 120, height: 120, borderRadius: 60, }, avatarPlaceholder: { width: 120, height: 120, borderRadius: 60, backgroundColor: '#E1E1E1', justifyContent: 'center', alignItems: 'center', }, changePhotoText: { marginTop: 8, color: '#007AFF', fontSize: 16, }, });