feature/IO-3687-Grey-Scale-Invisible-text - implement

This commit is contained in:
Dave
2026-05-06 16:45:00 -04:00
parent e0f55b8e7a
commit fcba77fe20
7 changed files with 302 additions and 25 deletions

View File

@@ -1,5 +1,5 @@
import axios from "axios";
import { Result } from "antd";
import { Result, theme } from "antd";
import * as markerjs2 from "markerjs2";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -9,6 +9,12 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto
import { handleUpload } from "../documents-local-upload/documents-local-upload.utility";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import {
addGreyscaleButtonToMarkerArea,
addImageHistoryUndoToMarkerArea,
applyGreyscaleToMarkerAreaImage,
setMarkerAreaImageSource
} from "./document-editor.utility";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
@@ -24,7 +30,9 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
const [imageLoaded, setImageLoaded] = useState(false);
const [imageLoading, setImageLoading] = useState(true);
const markerArea = useRef(null);
const imageHistory = useRef([]);
const { t } = useTranslation();
const { token } = theme.useToken();
const notification = useNotification();
const [uploading, setUploading] = useState(false);
@@ -32,6 +40,7 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
async (dataUrl) => {
if (uploading) return;
setUploading(true);
setLoading(true);
const blob = await b64toBlob(dataUrl);
const nameWithoutExt = filename.split(".").slice(0, -1).join(".").trim();
const parts = nameWithoutExt.split("-");
@@ -70,6 +79,23 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
[filename, jobid, notification, uploading]
);
const handleGreyscale = useCallback(() => {
if (!imgRef.current || loading || uploaded || imageLoading || !imageLoaded) return;
imageHistory.current.push(imgRef.current.src);
applyGreyscaleToMarkerAreaImage(markerArea.current, imgRef.current);
}, [imageLoaded, imageLoading, loading, uploaded]);
const undoImageEdit = useCallback(() => {
if (!imgRef.current) return;
const previousSrc = imageHistory.current.pop();
if (previousSrc) {
setMarkerAreaImageSource(markerArea.current, imgRef.current, previousSrc);
}
}, []);
useEffect(() => {
if (imgRef.current !== null && imageLoaded && !markerArea.current) {
// create a marker.js MarkerArea
@@ -93,8 +119,10 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
markerArea.current.renderImageQuality = 1;
//markerArea.current.settings.displayMode = "inline";
markerArea.current.show();
addGreyscaleButtonToMarkerArea(markerArea.current, handleGreyscale, t("documents.labels.greyscale"));
addImageHistoryUndoToMarkerArea(markerArea.current, () => imageHistory.current.length > 0, undoImageEdit);
}
}, [triggerUpload, imageLoaded]);
}, [handleGreyscale, imageLoaded, t, triggerUpload, undoImageEdit]);
useEffect(() => {
if (!imageUrl) return;
@@ -106,6 +134,7 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
try {
const response = await axios.get(imageUrl, { responseType: "blob", signal: controller.signal });
const blobUrl = URL.createObjectURL(response.data);
imageHistory.current = [];
setLoadedImageUrl((prevUrl) => {
if (prevUrl) URL.revokeObjectURL(prevUrl);
return blobUrl;
@@ -142,7 +171,7 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
}
return (
<div>
<div style={{ background: token.colorBgBase, color: token.colorText, minHeight: "100vh" }}>
{!loading && !uploaded && loadedImageUrl && (
<img
ref={imgRef}
@@ -158,7 +187,12 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
{(loading || imageLoading || !imageLoaded) && !uploaded && (
<LoadingSpinner message={t("documents.labels.uploading")} />
)}
{uploaded && <Result status="success" title={t("documents.successes.edituploaded")} />}
{uploaded && (
<Result
status="success"
title={<span style={{ color: token.colorText }}>{t("documents.successes.edituploaded")}</span>}
/>
)}
</div>
);
}