Browse Source

fix(photo-upload): implement smooth circular spinner loading matching Flutter ProfileAvatarWidget

master
mortezaei 2 days ago
parent
commit
120a753efd
  1. 21
      src/components/Componentes/question-photo.tsx

21
src/components/Componentes/question-photo.tsx

@ -23,7 +23,7 @@ export function QuestionPhoto({
}: QuestionPhotoProps) {
const inputId = useId();
const [localPreviewUrl, setLocalPreviewUrl] = useState<string | null>(null);
const [isFlutterPicking, setIsFlutterPicking] = useState(false);
const [isUploading, setIsUploading] = useState(false);
const acceptedFiles =
question.extras?.options && question.extras.options.length > 0
@ -41,13 +41,15 @@ export function QuestionPhoto({
setAnswerValue(question, response.path);
setLocalPreviewUrl(response.path);
}
setIsUploading(false);
},
onError: (error) => {
console.error("Photo upload error:", error);
setIsUploading(false);
},
});
const isPending = uploadTmpMediaMutation.isPending || isFlutterPicking;
const isPending = uploadTmpMediaMutation.isPending || isUploading;
// Listen for upload_file responses from Flutter WebView if active
useEffect(() => {
@ -60,9 +62,10 @@ export function QuestionPhoto({
switch (event.status) {
case "picking":
setIsFlutterPicking(true);
break;
case "picked":
case "progress":
setIsUploading(true);
if (event.data?.files?.[0]?.base64) {
const b64 = event.data.files[0].base64;
setLocalPreviewUrl(b64);
@ -70,7 +73,7 @@ export function QuestionPhoto({
}
break;
case "completed": {
setIsFlutterPicking(false);
setIsUploading(false);
isInitiatorRef.current = false;
const file = event.data?.files?.[0];
const remoteUrl =
@ -98,7 +101,7 @@ export function QuestionPhoto({
}
case "cancelled":
case "failed":
setIsFlutterPicking(false);
setIsUploading(false);
isInitiatorRef.current = false;
break;
}
@ -115,7 +118,6 @@ export function QuestionPhoto({
);
isInitiatorRef.current = true;
setIsFlutterPicking(true);
uploadFile({
requestId: String(question.id),
@ -142,6 +144,7 @@ export function QuestionPhoto({
setAnswerValue(question, objectUrl);
// Trigger background upload
setIsUploading(true);
uploadTmpMediaMutation.mutate(file);
};
@ -240,10 +243,10 @@ export function QuestionPhoto({
</span>
)}
{/* Loading spinner during upload */}
{/* Loading spinner during upload matching Flutter ProfileAvatarWidget */}
{isPending && (
<div className="absolute inset-0 flex items-center justify-center rounded-full bg-black/40 backdrop-blur-[1px]">
<LoadingSkeleton className="size-12 rounded-full" />
<div className="absolute inset-0 flex items-center justify-center rounded-full bg-black/40 backdrop-blur-[1px] z-10 transition-all duration-200">
<div className="h-7 w-7 animate-spin rounded-full border-[2.5px] border-white border-t-transparent shadow-sm" />
</div>
)}
</div>

Loading…
Cancel
Save