Browse Source

Merge branch 'staging' of https://git.nwhco.ir/sina_sajjadi/marriage into staging

staging
Ali Alavi 4 days ago
parent
commit
f8737c7da5
  1. 2
      src/components/Componentes/question-photo.test.tsx
  2. 23
      src/components/Componentes/question-photo.tsx
  3. 25
      src/hooks/marriage/use-upload-tmp-media.ts

2
src/components/Componentes/question-photo.test.tsx

@ -73,7 +73,7 @@ const mockPhotoQuestion: QuestionField = {
tooltip: "", tooltip: "",
extras: { extras: {
options: [".jpg", ".jpeg", ".png"], options: [".jpg", ".jpeg", ".png"],
},
} as any,
options: [], options: [],
}; };

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

@ -21,8 +21,9 @@ function base64ToFile(dataUrl: string, filename = "photo.jpg"): File {
const parts = dataUrl.split(","); const parts = dataUrl.split(",");
const mimeMatch = parts[0]?.match(/:(.*?);/); const mimeMatch = parts[0]?.match(/:(.*?);/);
const mime = mimeMatch ? mimeMatch[1] : "image/jpeg"; const mime = mimeMatch ? mimeMatch[1] : "image/jpeg";
const base64Data = parts[1] || parts[0];
const binaryString = atob(base64Data);
const rawBase64 = parts[1] || parts[0];
const cleanBase64 = rawBase64.replace(/\s+/g, "");
const binaryString = atob(cleanBase64);
const len = binaryString.length; const len = binaryString.length;
const bytes = new Uint8Array(len); const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
@ -201,14 +202,18 @@ export function QuestionPhoto({
}) })
.catch((err) => { .catch((err) => {
console.error("Flutter photo upload to server error:", err); console.error("Flutter photo upload to server error:", err);
handleUploadFailure();
const reason =
err?.response?.data?.reason ||
err?.response?.data?.detail ||
err?.message;
handleUploadFailure(reason);
pendingDeferredRef.current?.reject(err); pendingDeferredRef.current?.reject(err);
pendingDeferredRef.current = null; pendingDeferredRef.current = null;
}); });
registerPendingUpload?.(question.id, uploadPromise); registerPendingUpload?.(question.id, uploadPromise);
} catch (convErr) {
} catch (convErr: any) {
console.error("Failed to decode base64 photo:", convErr); console.error("Failed to decode base64 photo:", convErr);
handleUploadFailure();
handleUploadFailure(convErr?.message);
pendingDeferredRef.current?.reject(convErr); pendingDeferredRef.current?.reject(convErr);
pendingDeferredRef.current = null; pendingDeferredRef.current = null;
} }
@ -279,12 +284,18 @@ export function QuestionPhoto({
question.ui_config?.source || question.ui_config?.source ||
"gallery"; "gallery";
const uploadUrl =
typeof window !== "undefined"
? `${window.location.origin}/api/proxy?__proxyPath=/upload-tmp-media/`
: undefined;
uploadFile({ uploadFile({
requestId: String(question.id), requestId: String(question.id),
mediaType: "image", mediaType: "image",
source: pickerSource as any, source: pickerSource as any,
picker_type: pickerType as any, picker_type: pickerType as any,
returnAs: "base64",
returnAs: "upload",
uploadUrl,
fieldName: "file", fieldName: "file",
allowedExtensions: allowedExtensions:
extensions.length > 0 ? extensions : ["jpg", "jpeg", "png", "webp"], extensions.length > 0 ? extensions : ["jpg", "jpeg", "png", "webp"],

25
src/hooks/marriage/use-upload-tmp-media.ts

@ -5,25 +5,32 @@ import { http } from "@/lib/http";
import type { MutationOptions } from "./options"; import type { MutationOptions } from "./options";
import type { UploadTmpMediaResponse } from "./types"; import type { UploadTmpMediaResponse } from "./types";
const CSRF_TOKEN =
"53kqNKySTv3q4K3OolQqLEgaeF9pdPdAEnxrMARaUfvFrIGK57Qje67ifYUDMUQP";
import { getClientCookie } from "@/lib/cookies";
export async function uploadTmpMedia( export async function uploadTmpMedia(
file: File,
file: File | Blob,
onProgress?: (progressPercent: number) => void, onProgress?: (progressPercent: number) => void,
) { ) {
const formData = new FormData(); const formData = new FormData();
formData.append("file", file);
const filename = (file as File).name || "upload.jpg";
formData.append("file", file, filename);
const csrfToken =
getClientCookie("csrftoken") || getClientCookie("XSRF-TOKEN");
const headers: Record<string, string | undefined> = {
Accept: "application/json",
// Let browser/Axios automatically set multipart/form-data boundary
"Content-Type": undefined,
};
if (csrfToken) {
headers["X-CSRFToken"] = csrfToken;
}
const { data } = await http.post<UploadTmpMediaResponse>( const { data } = await http.post<UploadTmpMediaResponse>(
"/upload-tmp-media/", "/upload-tmp-media/",
formData, formData,
{ {
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
"X-CSRFToken": CSRF_TOKEN,
},
headers: headers as any,
onUploadProgress: (progressEvent) => { onUploadProgress: (progressEvent) => {
if (progressEvent.total && onProgress) { if (progressEvent.total && onProgress) {
const percent = Math.round( const percent = Math.round(

Loading…
Cancel
Save