default single placement for add image, signature and text tools
This commit is contained in:
committed by
Anthony Stirling
parent
8daee7303d
commit
b70c7b41e3
@@ -251,6 +251,8 @@ title = "How to add images"
|
||||
move = "Move Image"
|
||||
pause = "Pause placement"
|
||||
place = "Place Image"
|
||||
placeMultiple = "Stay in placement mode after each placement"
|
||||
placeMultipleDesc = "Place several images in a row instead of exiting after the first."
|
||||
resume = "Resume placement"
|
||||
|
||||
[addImage.results]
|
||||
@@ -440,6 +442,8 @@ title = "How to add text"
|
||||
move = "Move Text"
|
||||
pause = "Pause placement"
|
||||
place = "Place Text"
|
||||
placeMultiple = "Stay in placement mode after each placement"
|
||||
placeMultipleDesc = "Place several text stamps in a row instead of exiting after the first."
|
||||
resume = "Resume placement"
|
||||
|
||||
[addText.results]
|
||||
@@ -7127,6 +7131,8 @@ title = "How to add signature"
|
||||
move = "Move Signature"
|
||||
pause = "Pause placement"
|
||||
place = "Place Signature"
|
||||
placeMultiple = "Stay in placement mode after each placement"
|
||||
placeMultipleDesc = "Place several signatures in a row instead of exiting after the first."
|
||||
resume = "Resume placement"
|
||||
|
||||
[sign.results]
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
Tooltip,
|
||||
Group,
|
||||
Box,
|
||||
Checkbox,
|
||||
} from "@mantine/core";
|
||||
import { SignParameters } from "@app/hooks/tools/sign/useSignParameters";
|
||||
import { SuggestedToolsSection } from "@app/components/tools/shared/SuggestedToolsSection";
|
||||
@@ -92,7 +93,13 @@ const SignSettings = ({
|
||||
defaultSignatureSource,
|
||||
}: SignSettingsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { isPlacementMode, signaturesApplied, historyApiRef } = useSignature();
|
||||
const {
|
||||
isPlacementMode,
|
||||
signaturesApplied,
|
||||
historyApiRef,
|
||||
placeMultiple,
|
||||
setPlaceMultiple,
|
||||
} = useSignature();
|
||||
const { activeFileIndex } = useViewer();
|
||||
const [historyAvailability, setHistoryAvailability] = useState({
|
||||
canUndo: false,
|
||||
@@ -1215,6 +1222,20 @@ const SignSettings = ({
|
||||
<Box style={{ marginLeft: "auto" }}>{placementToggleControl}</Box>
|
||||
</Group>
|
||||
|
||||
<Checkbox
|
||||
checked={placeMultiple}
|
||||
onChange={(event) => setPlaceMultiple(event.currentTarget.checked)}
|
||||
label={translate(
|
||||
"mode.placeMultiple",
|
||||
"Stay in placement mode after each placement",
|
||||
)}
|
||||
description={translate(
|
||||
"mode.placeMultipleDesc",
|
||||
"Place several stamps in a row instead of exiting after the first.",
|
||||
)}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
<Alert color={placementAlert.color} title={placementAlert.title}>
|
||||
<Text size="sm">{placementAlert.message}</Text>
|
||||
</Alert>
|
||||
|
||||
@@ -185,7 +185,16 @@ export const SignatureAPIBridge = forwardRef<
|
||||
isPlacementMode,
|
||||
placementPreviewSize,
|
||||
setSignaturesApplied,
|
||||
placeMultiple,
|
||||
setPlacementMode,
|
||||
} = useSignature();
|
||||
// Track latest placeMultiple in a ref so the long-lived onAnnotationEvent
|
||||
// subscription always reads the current value without re-subscribing on every
|
||||
// toggle change (which would race with mid-flight create events).
|
||||
const placeMultipleRef = useRef(placeMultiple);
|
||||
useEffect(() => {
|
||||
placeMultipleRef.current = placeMultiple;
|
||||
}, [placeMultiple]);
|
||||
const { getZoomState, registerImmediateZoomUpdate } = useViewer();
|
||||
const documentReady = useDocumentReady();
|
||||
const [currentZoom, setCurrentZoom] = useState(
|
||||
@@ -555,6 +564,18 @@ export const SignatureAPIBridge = forwardRef<
|
||||
// Mark signatures as not applied when a new signature is placed
|
||||
if (event.type === "create") {
|
||||
setSignaturesApplied(false);
|
||||
|
||||
// Auto-exit placement mode after a single STAMP placement unless the
|
||||
// user opted into "place multiple". Only stamps trigger this — ink
|
||||
// strokes (signatureInk) are also create events but a multi-stroke
|
||||
// signature would break if we deactivated after the first stroke.
|
||||
const annotationType =
|
||||
annotation?.type ?? annotation?.object?.type ?? null;
|
||||
const isStamp = annotationType === PdfAnnotationSubtype.STAMP;
|
||||
if (isStamp && !placeMultipleRef.current) {
|
||||
annotationApi.setActiveTool(null);
|
||||
setPlacementMode(false);
|
||||
}
|
||||
}
|
||||
|
||||
const directData =
|
||||
@@ -576,7 +597,13 @@ export const SignatureAPIBridge = forwardRef<
|
||||
return () => {
|
||||
unsubscribe?.();
|
||||
};
|
||||
}, [annotationApi, storeImageData, setSignaturesApplied, documentReady]);
|
||||
}, [
|
||||
annotationApi,
|
||||
storeImageData,
|
||||
setSignaturesApplied,
|
||||
setPlacementMode,
|
||||
documentReady,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlacementMode || !documentReady) {
|
||||
|
||||
@@ -23,6 +23,10 @@ interface SignatureState {
|
||||
signaturesApplied: boolean;
|
||||
// Size (in screen units) we want newly placed signatures to use
|
||||
placementPreviewSize: { width: number; height: number } | null;
|
||||
// When false (default), placement mode auto-exits after a single stamp is
|
||||
// dropped so users don't accidentally place duplicates. When true, the user
|
||||
// opted into staying in placement mode and can drop multiple stamps in a row.
|
||||
placeMultiple: boolean;
|
||||
}
|
||||
|
||||
// Signature actions interface
|
||||
@@ -42,6 +46,7 @@ interface SignatureActions {
|
||||
setPlacementPreviewSize: (
|
||||
size: { width: number; height: number } | null,
|
||||
) => void;
|
||||
setPlaceMultiple: (enabled: boolean) => void;
|
||||
}
|
||||
|
||||
// Combined context interface
|
||||
@@ -62,6 +67,7 @@ const initialState: SignatureState = {
|
||||
isPlacementMode: false,
|
||||
signaturesApplied: true, // Start as true (no signatures placed yet)
|
||||
placementPreviewSize: null,
|
||||
placeMultiple: false,
|
||||
};
|
||||
|
||||
// Provider component
|
||||
@@ -174,6 +180,13 @@ export const SignatureProvider: React.FC<{ children: ReactNode }> = ({
|
||||
[],
|
||||
);
|
||||
|
||||
const setPlaceMultiple = useCallback((enabled: boolean) => {
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
placeMultiple: enabled,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// No auto-activation - all modes use manual buttons
|
||||
|
||||
const contextValue: SignatureContextValue = {
|
||||
@@ -194,6 +207,7 @@ export const SignatureProvider: React.FC<{ children: ReactNode }> = ({
|
||||
getImageData,
|
||||
setSignaturesApplied,
|
||||
setPlacementPreviewSize,
|
||||
setPlaceMultiple,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user