mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-07-07 13:55:19 +01:00
Fix MediaEditor CompositionInput enter key so it saves changes
Co-authored-by: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com>
This commit is contained in:
@@ -881,6 +881,82 @@ export function MediaEditor({
|
||||
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
||||
const handleSave = useCallback(async () => {
|
||||
if (!fabricCanvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
setEditMode(undefined);
|
||||
setIsSaving(true);
|
||||
|
||||
let data: Uint8Array<ArrayBuffer>;
|
||||
let blurHash: string;
|
||||
try {
|
||||
const renderFabricCanvas = await cloneFabricCanvas(fabricCanvas);
|
||||
|
||||
renderFabricCanvas.remove(
|
||||
...renderFabricCanvas.getObjects().filter(obj => obj.excludeFromExport)
|
||||
);
|
||||
|
||||
let finalImageState: ImageStateType;
|
||||
const pendingCrop = getPendingCrop(fabricCanvas);
|
||||
if (pendingCrop) {
|
||||
finalImageState = getNewImageStateFromCrop(imageState, pendingCrop);
|
||||
moveFabricObjectsForCrop(renderFabricCanvas, pendingCrop);
|
||||
drawFabricBackgroundImage({
|
||||
fabricCanvas: renderFabricCanvas,
|
||||
image,
|
||||
imageState: finalImageState,
|
||||
});
|
||||
} else {
|
||||
finalImageState = imageState;
|
||||
}
|
||||
|
||||
renderFabricCanvas.setDimensions({
|
||||
width: finalImageState.width,
|
||||
height: finalImageState.height,
|
||||
});
|
||||
renderFabricCanvas.setZoom(1);
|
||||
const renderedCanvas = renderFabricCanvas.toCanvasElement();
|
||||
|
||||
data = await canvasToBytes(renderedCanvas);
|
||||
|
||||
const blob = new Blob([data], {
|
||||
type: IMAGE_PNG,
|
||||
});
|
||||
|
||||
blurHash = await imageToBlurHash(blob);
|
||||
} catch (err) {
|
||||
onTryClose();
|
||||
throw err;
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
onDone({
|
||||
contentType: IMAGE_PNG,
|
||||
data,
|
||||
caption: caption !== '' ? caption : undefined,
|
||||
captionBodyRanges: captionBodyRanges ?? undefined,
|
||||
blurHash,
|
||||
isViewOnce: localIsViewOnce,
|
||||
isHighQuality: localIsHighQuality,
|
||||
});
|
||||
}, [
|
||||
captionBodyRanges,
|
||||
imageState,
|
||||
localIsHighQuality,
|
||||
localIsViewOnce,
|
||||
fabricCanvas,
|
||||
image,
|
||||
imageToBlurHash,
|
||||
caption,
|
||||
onDone,
|
||||
onTryClose,
|
||||
setEditMode,
|
||||
setIsSaving,
|
||||
]);
|
||||
|
||||
// In an ideal world we'd use <ModalHost /> to get the nice animation benefits
|
||||
// but because of the way IText is implemented -- with a hidden textarea -- to
|
||||
// capture keyboard events, we can't use ModalHost since that traps focus, and
|
||||
@@ -1416,7 +1492,7 @@ export function MediaEditor({
|
||||
}}
|
||||
emojiSkinToneDefault={emojiSkinToneDefault ?? null}
|
||||
onSelectEmoji={onSelectEmoji}
|
||||
onSubmit={noop}
|
||||
onSubmit={handleSave}
|
||||
onTextTooLong={onTextTooLong}
|
||||
ourConversationId={ourConversationId}
|
||||
placeholder={i18n('icu:MediaEditor__input-placeholder')}
|
||||
@@ -1452,78 +1528,7 @@ export function MediaEditor({
|
||||
size="md"
|
||||
disabled={!image}
|
||||
pending={isSaving || isSending}
|
||||
onClick={async () => {
|
||||
if (!fabricCanvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
setEditMode(undefined);
|
||||
setIsSaving(true);
|
||||
|
||||
let data: Uint8Array<ArrayBuffer>;
|
||||
let blurHash: string;
|
||||
try {
|
||||
const renderFabricCanvas =
|
||||
await cloneFabricCanvas(fabricCanvas);
|
||||
|
||||
renderFabricCanvas.remove(
|
||||
...renderFabricCanvas
|
||||
.getObjects()
|
||||
.filter(obj => obj.excludeFromExport)
|
||||
);
|
||||
|
||||
let finalImageState: ImageStateType;
|
||||
const pendingCrop = getPendingCrop(fabricCanvas);
|
||||
if (pendingCrop) {
|
||||
finalImageState = getNewImageStateFromCrop(
|
||||
imageState,
|
||||
pendingCrop
|
||||
);
|
||||
moveFabricObjectsForCrop(
|
||||
renderFabricCanvas,
|
||||
pendingCrop
|
||||
);
|
||||
drawFabricBackgroundImage({
|
||||
fabricCanvas: renderFabricCanvas,
|
||||
image,
|
||||
imageState: finalImageState,
|
||||
});
|
||||
} else {
|
||||
finalImageState = imageState;
|
||||
}
|
||||
|
||||
renderFabricCanvas.setDimensions({
|
||||
width: finalImageState.width,
|
||||
height: finalImageState.height,
|
||||
});
|
||||
renderFabricCanvas.setZoom(1);
|
||||
const renderedCanvas =
|
||||
renderFabricCanvas.toCanvasElement();
|
||||
|
||||
data = await canvasToBytes(renderedCanvas);
|
||||
|
||||
const blob = new Blob([data], {
|
||||
type: IMAGE_PNG,
|
||||
});
|
||||
|
||||
blurHash = await imageToBlurHash(blob);
|
||||
} catch (err) {
|
||||
onTryClose();
|
||||
throw err;
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
onDone({
|
||||
contentType: IMAGE_PNG,
|
||||
data,
|
||||
caption: caption !== '' ? caption : undefined,
|
||||
captionBodyRanges: captionBodyRanges ?? undefined,
|
||||
blurHash,
|
||||
isViewOnce: localIsViewOnce,
|
||||
isHighQuality: localIsHighQuality,
|
||||
});
|
||||
}}
|
||||
onClick={handleSave}
|
||||
>
|
||||
{doneButtonLabel || i18n('icu:save')}
|
||||
</AxoButton.Root>
|
||||
|
||||
Reference in New Issue
Block a user