import { useState, useCallback } from 'react' import { ImagePickerAsset, launchImageLibraryAsync, MediaTypeOptions } from 'expo-image-picker' import Toast from '@/components/ui/Toast' import { updateUser } from '@/lib/auth' import { uploadFile } from '@/lib/uploadFile' import { type ApiError } from '@/lib/types' export interface UpdateProfileParams { name?: string image?: ImagePickerAsset } export function useUpdateProfile() { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) /** * 选择图片 */ const pickImage = useCallback(async (): Promise => { try { const result = await launchImageLibraryAsync({ mediaTypes: MediaTypeOptions.Images, allowsEditing: true, aspect: [1, 1], quality: 0.8, }) if (result.canceled) { return null } return result.assets[0] || null } catch (err) { console.error('选择图片失败:', err) Toast.show('选择图片失败') return null } }, []) /** * 更新用户资料 */ const updateProfile = useCallback(async (params: UpdateProfileParams) => { setLoading(true) setError(null) try { const updateData: Record = {} // 如果有新头像,先上传图片 if (params.image) { Toast.showLoading({ title: '上传头像中...' }) try { const imageUrl = await uploadFile({ uri: params.image.uri, mimeType: params.image.mimeType || 'image/jpeg', fileName: `avatar_${Date.now()}.jpg`, }) updateData.image = imageUrl Toast.hideLoading() } catch (err) { Toast.hideLoading() throw new Error('头像上传失败') } } // 更新用户名 if (params.name) { updateData.name = params.name } // 如果有数据需要更新 if (Object.keys(updateData).length > 0) { Toast.showLoading({ title: '保存中...' }) const result = await updateUser(updateData) Toast.hideLoading() if (result.error) { throw result.error } Toast.show('保存成功') return { data: result.data, error: null } } return { data: null, error: null } } catch (err) { const errorObj = err as ApiError setError(errorObj) Toast.show(errorObj.message || '保存失败,请稍后重试') return { data: null, error: errorObj } } finally { setLoading(false) } }, []) return { loading, error, pickImage, updateProfile, } }