commit 668004de21e492c193651a6dd67d2a91349191c7
parent 32a4fe6b3e2ea78313fa57f96ec8e31df2e2f148
Author: Sebastian <sebasjm@taler-systems.com>
Date: Fri, 30 Jan 2026 13:31:09 -0300
fix #10952
Diffstat:
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())
+ };
+ })
+}