diff --git a/packages/jsActions/nanoflow-actions-native/src/other/Base64DecodeToImage.ts b/packages/jsActions/nanoflow-actions-native/src/other/Base64DecodeToImage.ts index f7243f73d..6b1ff8f7c 100644 --- a/packages/jsActions/nanoflow-actions-native/src/other/Base64DecodeToImage.ts +++ b/packages/jsActions/nanoflow-actions-native/src/other/Base64DecodeToImage.ts @@ -6,6 +6,7 @@ // - the code between BEGIN EXTRA CODE and END EXTRA CODE // Other code you write will be lost the next time you deploy the project. import { Base64 } from "js-base64"; +import RNBlobUtil from "react-native-blob-util"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -16,7 +17,7 @@ import { Base64 } from "js-base64"; * @param {MxObject} image * @returns {Promise.} */ -export function Base64DecodeToImage(base64: string, image: mendix.lib.MxObject): Promise { +export async function Base64DecodeToImage(base64: string, image: mendix.lib.MxObject): Promise { // BEGIN USER CODE if (!base64) { @@ -26,6 +27,56 @@ export function Base64DecodeToImage(base64: string, image: mendix.lib.MxObject): throw new Error("image should not be null"); } + // Native platform + if (navigator && navigator.product === "ReactNative") { + try { + // Remove data URI prefix if present (e.g., "data:image/png;base64,") + let cleanBase64 = base64; + if (base64.includes(",")) { + cleanBase64 = base64.split(",")[1]; + } + + // Remove any whitespace/newlines + cleanBase64 = cleanBase64.replace(/\s/g, ""); + + // Validate base64 format + if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleanBase64)) { + throw new Error("Invalid base64 format"); + } + + // Create a temporary file path + const tempPath = `${RNBlobUtil.fs.dirs.CacheDir}/temp_image_${Date.now()}.png`; + + // Write Base64 data to a temporary file + await RNBlobUtil.fs.writeFile(tempPath, cleanBase64, "base64"); + + // Fetch the file as a blob + const res = await fetch(`file://${tempPath}`); + const blob = await res.blob(); + + return new Promise((resolve, reject) => { + mx.data.saveDocument( + image.getGuid(), + "camera image", + {}, + blob, + () => { + RNBlobUtil.fs.unlink(tempPath).catch(e => console.info("Temp file cleanup failed:", e)); + resolve(true); + }, + error => { + RNBlobUtil.fs.unlink(tempPath).catch(e => console.info("Temp file cleanup failed:", e)); + reject(error); + } + ); + }); + } catch (error) { + console.error("Failed to decode base64 to image:", error); + return false; + } + } + + // Other platforms const blob = new Blob([Base64.toUint8Array(base64)], { type: "image/png" }); return new Promise((resolve, reject) => {