taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 668004de21e492c193651a6dd67d2a91349191c7
parent 32a4fe6b3e2ea78313fa57f96ec8e31df2e2f148
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Fri, 30 Jan 2026 13:31:09 -0300

fix #10952

Diffstat:
Mpackages/merchant-backoffice-ui/src/components/form/InputImage.tsx | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 53 insertions(+), 18 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx @@ -78,27 +78,18 @@ export function InputImage<T>({ placeholder={placeholder} readonly={readonly} onChange={(e) => { - const f: FileList | null = e.currentTarget.files; - console.log("on change", e, f); - if (!f || f.length != 1) { + const fileList: FileList | null = e.currentTarget.files; + if (!fileList || fileList.length != 1) { return onChange(undefined!); } - if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { + if (fileList[0].size > MAX_IMAGE_UPLOAD_SIZE) { setSizeError(true); - return onChange(undefined!); + normalizeImagesize(fileList[0], onChange as any) + // return onChange(undefined!); + return; } setSizeError(false); - return f[0].arrayBuffer().then((b) => { - const b64 = window.btoa( - new Uint8Array(b).reduce( - (data, byte) => data + String.fromCharCode(byte), - "", - ), - ); - return onChange( - `data:${f[0].type};base64,${b64}` as T[keyof T], - ); - }); + onChange(toDataSrc(fileList[0]) as T[keyof T]) }} /> {help} @@ -110,8 +101,8 @@ export function InputImage<T>({ </p> )} {sizeError && ( - <p class="help is-danger" style={{ fontSize: 16 }}> - <i18n.Translate>Image must be smaller than 1 MB</i18n.Translate> + <p class="help" style={{ fontSize: 16 }}> + <i18n.Translate>The image was normalized to be smaller than 1 MB</i18n.Translate> </p> )} {!value && ( @@ -128,6 +119,7 @@ export function InputImage<T>({ image.current.value = ""; } onChange(undefined!); + setSizeError(false) }} > <i18n.Translate>Remove</i18n.Translate> @@ -138,3 +130,46 @@ export function InputImage<T>({ </div> ); } + +async function toDataSrc(imageFile: File): Promise<string> { + return imageFile.arrayBuffer().then((b) => { + const b64 = window.btoa( + new Uint8Array(b).reduce( + (data, byte) => data + String.fromCharCode(byte), + "", + ), + ); + return (`data:${imageFile.type};base64,${b64}`); + }) +} + +const IMAGE_MAX_WIDTH = 800; +const IMAGE_MAX_HEIGHT = 800; +function normalizeImagesize(imageFile: File, onComplete: (d: string) => void) { + toDataSrc(imageFile).then(imageSource => { + const img = new Image(); + img.src = imageSource; + img.onload = function () { + const canvas = document.createElement('canvas') as HTMLCanvasElement; + const ctx = canvas.getContext('2d')!; + + let width = img.width; + let height = img.height; + if (width > height) { + if (width > IMAGE_MAX_WIDTH) { + height *= IMAGE_MAX_WIDTH / width; + width = IMAGE_MAX_WIDTH; + } + } else { + if (height > IMAGE_MAX_HEIGHT) { + width *= IMAGE_MAX_HEIGHT / height; + height = IMAGE_MAX_HEIGHT; + } + } + canvas.width = width; + canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + onComplete(canvas.toDataURL()) + }; + }) +}