Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ef112dc
chore: add mendix native as dependency
SrirangK Aug 31, 2026
7e30552
fix: replace local references
SrirangK Aug 31, 2026
7061b88
fix: mendix-native web issue
SrirangK Aug 31, 2026
2fa8ea9
fix: mendix-native tarball
SrirangK Aug 31, 2026
ca6a725
chore: update mendix native version
SrirangK Aug 31, 2026
14c0ba5
fix: restore mendix-native 0.5.2 for e2e app startup
Copilot Sep 1, 2026
ec180a5
Revert "fix: restore mendix-native 0.5.2 for e2e app startup"
SrirangK Sep 1, 2026
726ab9e
fix: scope modules
SrirangK Sep 1, 2026
f3f2bd4
fix: update tarball
SrirangK Sep 1, 2026
ac90f51
fix: try adding geolocation dependency
SrirangK Sep 1, 2026
fe4b137
chore: capture logcat
SrirangK Sep 2, 2026
692d9c9
chore: capture logcat
SrirangK Sep 2, 2026
1b55297
fix: add module scope to nw
SrirangK Sep 3, 2026
6f882ec
fix: video player mpk size
SrirangK Sep 3, 2026
9ffdf02
fix: mendix sp version
SrirangK Sep 4, 2026
c347e69
fix: expose mendix native from sp
SrirangK Sep 4, 2026
a4a8adc
fix: rollup
SrirangK Sep 4, 2026
150179a
fix: remove tourbomoduleregistry
SrirangK Sep 7, 2026
6b47264
chore: remove unnecessary changes
SrirangK Sep 7, 2026
8fc9f34
fix: web build issue
SrirangK Sep 8, 2026
bf6c007
fix: import style
SrirangK Sep 9, 2026
121d980
chore: remove extra comments
SrirangK Sep 9, 2026
175411b
chore: update native imports
YogendraShelke Sep 10, 2026
cbcec0f
fix: import style
SrirangK Sep 10, 2026
4a929c9
fix: replace Native modules import
SrirangK Sep 11, 2026
7be739f
fix: hasnotificationpermission migration
SrirangK Sep 15, 2026
6494866
chore: update minimum MX version
SrirangK Sep 29, 2026
37cb5a9
chore: delete mendix-native-0.6.0.tgz
SrirangK Sep 30, 2026
8705e5b
chore: update mx latest version to 11.15.0
SrirangK Oct 1, 2026
ccd6b23
chore: bump version and add changelogs
SrirangK Oct 5, 2026
b7b9378
fix: pnpm lock
SrirangK Oct 9, 2026
0cb5f5b
fix: pnpm lock
SrirangK Oct 19, 2026
6619332
chore: new NATIVE_DEPENDENCY_APPROVED
SrirangK Oct 19, 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.14.0"
"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