@@ -97,41 +97,45 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
|
|||||||
}, [triggerUpload, imageLoaded]);
|
}, [triggerUpload, imageLoaded]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Load the image from imageUrl
|
if (!imageUrl) return;
|
||||||
let isCancelled = false;
|
const controller = new AbortController();
|
||||||
|
|
||||||
const loadImage = async () => {
|
const loadImage = async () => {
|
||||||
if (!imageUrl) return;
|
|
||||||
|
|
||||||
setImageLoaded(false);
|
setImageLoaded(false);
|
||||||
setImageLoading(true);
|
setImageLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(imageUrl, { responseType: "blob" });
|
const response = await axios.get(imageUrl, { responseType: "blob", signal: controller.signal });
|
||||||
|
|
||||||
if (isCancelled) return;
|
|
||||||
|
|
||||||
const blobUrl = URL.createObjectURL(response.data);
|
const blobUrl = URL.createObjectURL(response.data);
|
||||||
setLoadedImageUrl((prevUrl) => {
|
setLoadedImageUrl((prevUrl) => {
|
||||||
if (prevUrl) URL.revokeObjectURL(prevUrl);
|
if (prevUrl) URL.revokeObjectURL(prevUrl);
|
||||||
return blobUrl;
|
return blobUrl;
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (axios.isCancel?.(error) || error.name === "CanceledError") {
|
||||||
|
// request was aborted — safe to ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.error("Failed to fetch image blob", error);
|
console.error("Failed to fetch image blob", error);
|
||||||
} finally {
|
} finally {
|
||||||
if (!isCancelled) {
|
if (!controller.signal.aborted) {
|
||||||
setImageLoading(false);
|
setImageLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadImage();
|
loadImage();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
isCancelled = true;
|
controller.abort();
|
||||||
};
|
};
|
||||||
}, [imageUrl]);
|
}, [imageUrl]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (loadedImageUrl) {
|
||||||
|
URL.revokeObjectURL(loadedImageUrl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [loadedImageUrl]);
|
||||||
|
|
||||||
async function b64toBlob(url) {
|
async function b64toBlob(url) {
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
return await res.blob();
|
return await res.blob();
|
||||||
|
|||||||
@@ -84,45 +84,50 @@ export function DocumentEditorComponent({ currentUser, bodyshop, document }) {
|
|||||||
}, [triggerUpload, imageLoaded]);
|
}, [triggerUpload, imageLoaded]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// When the document changes, fetch the image via axios so auth and base URL are applied
|
if (!document?.id) return;
|
||||||
let isCancelled = false;
|
const controller = new AbortController();
|
||||||
|
|
||||||
const loadImage = async () => {
|
const loadImage = async () => {
|
||||||
if (!document || !document.id) return;
|
|
||||||
|
|
||||||
setImageLoaded(false);
|
setImageLoaded(false);
|
||||||
setImageLoading(true);
|
setImageLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
"/media/imgproxy/original",
|
"/media/imgproxy/original",
|
||||||
{ documentId: document.id },
|
{ documentId: document.id },
|
||||||
{ responseType: "blob" }
|
{
|
||||||
|
responseType: "blob",
|
||||||
|
signal: controller.signal
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isCancelled) return;
|
|
||||||
|
|
||||||
const blobUrl = URL.createObjectURL(response.data);
|
const blobUrl = URL.createObjectURL(response.data);
|
||||||
setImageUrl((prevUrl) => {
|
setImageUrl((prevUrl) => {
|
||||||
if (prevUrl) URL.revokeObjectURL(prevUrl);
|
if (prevUrl) URL.revokeObjectURL(prevUrl);
|
||||||
return blobUrl;
|
return blobUrl;
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (axios.isCancel?.(error) || error.name === "CanceledError") {
|
||||||
|
// request was aborted — safe to ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.error("Failed to fetch original image blob", error);
|
console.error("Failed to fetch original image blob", error);
|
||||||
} finally {
|
} finally {
|
||||||
if (!isCancelled) {
|
setImageLoading(false);
|
||||||
setImageLoading(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadImage();
|
loadImage();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
isCancelled = true;
|
controller.abort();
|
||||||
};
|
};
|
||||||
}, [document]);
|
}, [document]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (imageUrl) {
|
||||||
|
URL.revokeObjectURL(imageUrl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [imageUrl]);
|
||||||
|
|
||||||
async function b64toBlob(url) {
|
async function b64toBlob(url) {
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
return await res.blob();
|
return await res.blob();
|
||||||
|
|||||||
@@ -33,6 +33,19 @@ export function DocumentEditorContainer({ setBodyshop }) {
|
|||||||
nextFetchPolicy: "network-only"
|
nextFetchPolicy: "network-only"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isLocalMedia = !!dataShop?.bodyshops?.[0]?.uselocalmediaserver;
|
||||||
|
|
||||||
|
const {
|
||||||
|
loading: loadingDoc,
|
||||||
|
error: errorDoc,
|
||||||
|
data: dataDoc
|
||||||
|
} = useQuery(GET_DOCUMENT_BY_PK, {
|
||||||
|
variables: { documentId },
|
||||||
|
skip: !documentId || isLocalMedia,
|
||||||
|
fetchPolicy: "network-only",
|
||||||
|
nextFetchPolicy: "network-only"
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (dataShop) setBodyshop(dataShop.bodyshops[0]);
|
if (dataShop) setBodyshop(dataShop.bodyshops[0]);
|
||||||
}, [dataShop, setBodyshop]);
|
}, [dataShop, setBodyshop]);
|
||||||
@@ -40,7 +53,7 @@ export function DocumentEditorContainer({ setBodyshop }) {
|
|||||||
if (loadingShop) return <LoadingSpinner />;
|
if (loadingShop) return <LoadingSpinner />;
|
||||||
if (errorShop) return <AlertComponent message={errorShop.message} type="error" />;
|
if (errorShop) return <AlertComponent message={errorShop.message} type="error" />;
|
||||||
|
|
||||||
if (dataShop?.bodyshops[0]?.uselocalmediaserver) {
|
if (isLocalMedia) {
|
||||||
if (imageUrl && filename && jobid) {
|
if (imageUrl && filename && jobid) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -52,20 +65,13 @@ export function DocumentEditorContainer({ setBodyshop }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { loading, error, data } = useQuery(GET_DOCUMENT_BY_PK, {
|
if (loadingDoc) return <LoadingSpinner />;
|
||||||
variables: { documentId },
|
if (errorDoc) return <AlertComponent message={errorDoc.message} type="error" />;
|
||||||
skip: !documentId,
|
|
||||||
fetchPolicy: "network-only",
|
|
||||||
nextFetchPolicy: "network-only"
|
|
||||||
});
|
|
||||||
|
|
||||||
if (loading) return <LoadingSpinner />;
|
if (!dataDoc || !dataDoc.documents_by_pk) return <Result status="404" title={t("general.errors.notfound")} />;
|
||||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
|
||||||
|
|
||||||
if (!data || !data.documents_by_pk) return <Result status="404" title={t("general.errors.notfound")} />;
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<DocumentEditor document={data ? data.documents_by_pk : null} />
|
<DocumentEditor document={dataDoc ? dataDoc.documents_by_pk : null} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ export function JobsDocumentsLocalGallery({
|
|||||||
key="edit"
|
key="edit"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const newWindow = window.open(
|
const newWindow = window.open(
|
||||||
`${window.location.protocol}//${window.location.host}/edit-local?imageUrl=${
|
`${window.location.protocol}//${window.location.host}/edit?imageUrl=${
|
||||||
jobMedia.images[modalState.index].fullsize
|
jobMedia.images[modalState.index].fullsize
|
||||||
}&filename=${jobMedia.images[modalState.index].filename}&jobid=${job.id}`,
|
}&filename=${jobMedia.images[modalState.index].filename}&jobid=${job.id}`,
|
||||||
"_blank",
|
"_blank",
|
||||||
|
|||||||
Reference in New Issue
Block a user