Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
df021a0
chore: add mendix native as dependency
SrirangK Aug 31, 2026
6348bc2
fix: replace local references
SrirangK Aug 31, 2026
6e61e11
fix: mendix-native web issue
SrirangK Aug 31, 2026
6d5921e
fix: mendix-native tarball
SrirangK Aug 31, 2026
0dc3ae6
chore: update mendix native version
SrirangK Aug 31, 2026
a3a1f14
fix: restore mendix-native 0.5.2 for e2e app startup
Copilot Sep 1, 2026
39ad6d6
Revert "fix: restore mendix-native 0.5.2 for e2e app startup"
SrirangK Sep 1, 2026
8783940
fix: scope modules
SrirangK Sep 1, 2026
0b95397
fix: update tarball
SrirangK Sep 1, 2026
660a48b
fix: try adding geolocation dependency
SrirangK Sep 1, 2026
9511dc3
chore: capture logcat
SrirangK Sep 2, 2026
1f7894a
chore: capture logcat
SrirangK Sep 2, 2026
1cb85e2
fix: add module scope to nw
SrirangK Sep 3, 2026
326f0bc
fix: video player mpk size
SrirangK Sep 3, 2026
ceee0ca
fix: mendix sp version
SrirangK Sep 4, 2026
b0449a5
fix: expose mendix native from sp
SrirangK Sep 4, 2026
735cfa3
fix: rollup
SrirangK Sep 4, 2026
330a3b6
fix: remove tourbomoduleregistry
SrirangK Sep 7, 2026
ca521ab
chore: remove unnecessary changes
SrirangK Sep 7, 2026
d0bf640
fix: web build issue
SrirangK Sep 8, 2026
8534400
fix: import style
SrirangK Sep 9, 2026
b184fb8
chore: remove extra comments
SrirangK Sep 9, 2026
fac3ea1
chore: update native imports
YogendraShelke Sep 10, 2026
78efb0b
chore: remove unnecessaryy changes from pnpm-lock
SrirangK Sep 10, 2026
48c967f
fix: import style
SrirangK Sep 10, 2026
85924a8
fix: replace Native modules import
SrirangK Sep 11, 2026
ae85ec3
fix: hasnotificationpermission migration
SrirangK Sep 15, 2026
0617d75
chore: update minimum MX version
SrirangK Sep 29, 2026
b194a97
chore: update pnpm.lock
SrirangK Sep 29, 2026
3814782
chore: delete mendix-native-0.6.0.tgz
SrirangK Sep 30, 2026
21fb80f
chore: update mx latest version to 11.15.0
SrirangK Oct 1, 2026
8761e39
chore: bump version and add changelogs
SrirangK Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion configs/e2e/mendix-versions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"latest": "11.12.3"
"latest": "11.15.0"
}
1 change: 1 addition & 0 deletions configs/jsactions/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export default async args => {

const nativeExternal = [
/^mendix\//,
/^mendix-native(\/|$)/,
/^react-native(\/|$)/,
/^react-native-windows(\/|$)/,
/^react-native-web(\/|$)/,
Expand Down
4 changes: 4 additions & 0 deletions packages/jsActions/mobile-resources-native/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Fixed an issue where the `TakePicture` and `TakePictureAdvanced` actions did not properly clean up temporary files.
- Replaced @notifee/react-native with react-native-notify-kit library.

### Added

- We added mendix-native as a dependency to provide native file system.

## [12.1.0] Native Mobile Resources - 2026-6-10

- Updated react-native from version 0.83.4 to 0.84.1.
Expand Down
3 changes: 2 additions & 1 deletion packages/jsActions/mobile-resources-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"marketplace": {
"name": "Native Mobile Resources",
"description": "Download this module to access a rich set of widgets and nanoflow actions created for native mobile, including authentication, network, platform, and more. A must-have for native mobile development!",
"minimumMXVersion": "11.12.3",
"minimumMXVersion": "11.15.0",
"marketplaceId": 109513
},
"testProject": {
Expand All @@ -34,6 +34,7 @@
"@sbaiahmed1/react-native-biometrics": "0.15.0",
"@swan-io/react-native-browser": "1.0.1",
"fbjs": "3.0.4",
"mendix-native": "https://github.com/mendix/mendix-native/releases/download/v0.6.0/mendix-native-v0.6.0.tgz",
"mime": "3.0.0",
"react-native-blob-util": "0.24.7",
"react-native-device-info": "15.0.2",
Expand Down
106 changes: 10 additions & 96 deletions packages/jsActions/mobile-resources-native/src/camera/TakePicture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
// - 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 { Big } from "big.js";
import { Alert, Linking, NativeModules, Platform } from "react-native";
import { NativeFileSystem } from "mendix-native";
import { Alert, Linking, Platform } from "react-native";
import {
CameraOptions,
ErrorCode,
Expand All @@ -16,7 +17,8 @@ import {
launchImageLibrary
} from "react-native-image-picker";
import { getLocales } from "react-native-localize";
import { ImagePickerV2Options, ImagePickerV2Response, PictureQuality, PictureSource } from "../../typings/Camera";
import RNPermissions from "react-native-permissions";
import { PictureQuality, PictureSource } from "../../typings/Camera";

// BEGIN EXTRA CODE
// END EXTRA CODE
Expand Down Expand Up @@ -55,10 +57,6 @@ export async function TakePicture(
);
}

// V3 dropped the feature of providing an action sheet so users can decide on which action to take, camera or library.
const nativeVersionMajor = NativeModules?.ImagePickerManager?.showImagePicker ? 2 : 4;
const RNPermissions = nativeVersionMajor === 4 ? (await import("react-native-permissions")).default : null;

try {
const uri = await takePicture();

Expand All @@ -77,32 +75,14 @@ export async function TakePicture(

function takePicture(): Promise<string | undefined> {
return new Promise((resolve, reject) => {
const options = nativeVersionMajor === 2 ? getOptionsV2() : getOptions();
const options = getOptions();
getPictureMethod()
.then(method =>
method(options, (response: ImagePickerV2Response | ImagePickerResponse) => {
method(options, (response: ImagePickerResponse) => {
if (response.didCancel) {
return resolve(undefined);
}

if (nativeVersionMajor === 2) {
const responseV2 = response as ImagePickerV2Response;

if (responseV2.error) {
const unhandledError = handleImagePickerV2Error(responseV2.error);

if (!unhandledError) {
return resolve(undefined);
}

return reject(new Error(responseV2.error));
}

return resolve(responseV2.uri);
}

response = response as ImagePickerResponse;

if (response.errorCode) {
handleImagePickerV4Error(response.errorCode, response.errorMessage);

Expand All @@ -118,7 +98,7 @@ export async function TakePicture(

async function safeRemove(filePath: string): Promise<void> {
try {
await NativeModules.MxFileSystem.remove(filePath);
await NativeFileSystem.remove(filePath);
} catch (error) {
console.warn(`Failed to remove file at ${filePath}. Error: ${error}`);
// ignore error
Expand All @@ -127,7 +107,7 @@ export async function TakePicture(

function storeFile(imageObject: mendix.lib.MxObject, uri: string): Promise<boolean> {
return new Promise((resolve, reject) => {
NativeModules.MxFileSystem.read(uri.replace("file://", ""))
NativeFileSystem.read(uri.replace("file://", ""))
.then((nativeBlob: unknown) => {
const blob = new Blob();
Object.assign(blob, { data: nativeBlob });
Expand Down Expand Up @@ -169,13 +149,10 @@ export async function TakePicture(
}

async function getPictureMethod(): Promise<
(
options: ImagePickerV2Options | CameraOptions | ImageLibraryOptions,
callback: (response: ImagePickerV2Response | ImagePickerResponse) => void
) => void
(options: CameraOptions | ImageLibraryOptions, callback: (response: ImagePickerResponse) => void) => void
> {
async function handleCameraRequest(): Promise<typeof launchCamera> {
if (Platform.OS === "android" && nativeVersionMajor === 4) {
if (Platform.OS === "android") {
await checkAndMaybeRequestAndroidPermission();
}

Expand Down Expand Up @@ -225,38 +202,6 @@ export async function TakePicture(
}
}

function getOptionsV2(): ImagePickerV2Options {
const { maxWidth, maxHeight } = getPictureQuality();
const [language] = getLocales().map(local => local.languageCode);
const isDutch = language === "nl";

return {
mediaType: "photo" as const,
maxWidth,
maxHeight,
noData: true,
title: isDutch ? "Foto toevoegen" : "Select a photo",
cancelButtonTitle: isDutch ? "Annuleren" : "Cancel",
takePhotoButtonTitle: isDutch ? "Foto maken" : "Take photo",
chooseFromLibraryButtonTitle: isDutch ? "Kies uit bibliotheek" : "Choose from library",
permissionDenied: {
title: isDutch
? "Deze app heeft geen toegang tot uw camera of foto bibliotheek"
: "This app does not have access to your camera or photo library",
text: isDutch
? "Ga naar Instellingen > Privacy om toegang tot uw camera en bestanden te verlenen."
: "To enable access, tap Settings > Privacy and turn on Camera and Photos/Storage.",
reTryTitle: isDutch ? "Instellingen" : "Settings",
okTitle: isDutch ? "Annuleren" : "Cancel"
},
storageOptions: {
skipBackup: true,
cameraRoll: false,
privateDirectory: true
}
};
}

function getOptions(): CameraOptions | ImageLibraryOptions {
const { maxWidth, maxHeight } = getPictureQuality();
return {
Expand Down Expand Up @@ -293,37 +238,6 @@ export async function TakePicture(
}
}

function handleImagePickerV2Error(error: string): string | undefined {
const ERRORS = {
AndroidPermissionDenied: "Permissions weren't granted",
iOSPhotoLibraryPermissionDenied: "Photo library permissions not granted",
iOSCameraPermissionDenied: "Camera permissions not granted"
};

switch (error) {
case ERRORS.iOSPhotoLibraryPermissionDenied:
showAlert(
"This app does not have access to your photo library",
"To enable access, tap Settings and turn on Photos."
);
return;

case ERRORS.iOSCameraPermissionDenied:
showAlert(
"This app does not have access to your camera",
"To enable access, tap Settings and turn on Camera."
);
return;

case ERRORS.AndroidPermissionDenied:
// Ignore this error because the image picker plugin already shows an alert in this case.
return;

default:
return error;
}
}

function showAlert(title: string, message: string): void {
Alert.alert(
title,
Expand Down
Loading
Loading