From 982221ef6493915d7cd2c312cfd7c2ff1e119875 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 09:47:35 +0200 Subject: [PATCH 01/23] migrate push notification to notifee --- .../mobile-resources-native/package.json | 8 +- .../CancelAllScheduledNotifications.ts | 6 +- .../CancelScheduledNotification.ts | 6 +- .../ClearAllDeliveredNotifications.ts | 6 +- .../src/notifications/DisplayNotification.ts | 81 ++++++++-------- .../src/notifications/ScheduleNotification.ts | 93 +++++++++---------- .../src/notifications/SetBadgeNumber.ts | 6 +- .../notifications-native/package.json | 4 +- .../src/Notifications.tsx | 30 +++--- yarn.lock | 48 +++------- 10 files changed, 127 insertions(+), 161 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/package.json b/packages/jsActions/mobile-resources-native/package.json index c003ad8ab..ac8cef09a 100644 --- a/packages/jsActions/mobile-resources-native/package.json +++ b/packages/jsActions/mobile-resources-native/package.json @@ -26,10 +26,10 @@ "release:marketplace": "node ../../../scripts/release/marketplaceRelease.js" }, "dependencies": { + "@notifee/react-native": "9.1.8", "@react-native-camera-roll/camera-roll": "7.4.0", - "@react-native-community/push-notification-ios": "1.10.1", "@react-native-firebase/messaging": "17.3.0", - "@swan-io/react-native-browser": "^0.4.1", + "@swan-io/react-native-browser": "0.4.1", "fbjs": "3.0.4", "mime": "3.0.0", "react-native-blob-util": "0.21.2", @@ -38,7 +38,6 @@ "react-native-image-picker": "7.2.3", "react-native-localize": "3.2.1", "react-native-permissions": "4.1.5", - "react-native-push-notification": "8.1.1", "react-native-schedule-exact-alarm-permission": "^0.1.3", "react-native-sound": "0.11.0", "react-native-touch-id": "4.4.1", @@ -47,11 +46,10 @@ "devDependencies": { "@mendix/pluggable-widgets-tools": "^10.0.1", "@types/querystringify": "^2.0.0", - "@types/react-native-push-notification": "8.1.1", "@types/url-parse": "^1.4.3", "eslint": "^7.32.0", "mendix": "~10.0.9976", "rimraf": "^4.4.1", "rollup": "^2.79.2" } -} \ No newline at end of file +} diff --git a/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts b/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts index f47fde625..092b821f4 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts @@ -6,7 +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 { NativeModules, Platform } from "react-native"; -import PushNotification from "react-native-push-notification"; +import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -17,13 +17,13 @@ import PushNotification from "react-native-push-notification"; */ export async function CancelAllScheduledNotifications(): Promise { // BEGIN USER CODE - // Documentation https://github.com/zo0r/react-native-push-notification + // Documentation https://github.com/invertase/notifee const isIOS = Platform.OS === "ios"; if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { return Promise.reject(new Error("Notifications module is not available in your app")); } - PushNotification.cancelAllLocalNotifications(); + notifee.cancelAllNotifications(); return Promise.resolve(); // END USER CODE diff --git a/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts index 20b1ab7b8..ddcd5979c 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts @@ -6,7 +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 { NativeModules, Platform } from "react-native"; -import PushNotification from "react-native-push-notification"; +import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -17,7 +17,7 @@ import PushNotification from "react-native-push-notification"; */ export async function CancelScheduledNotification(notificationId?: string): Promise { // BEGIN USER CODE - // Documentation https://github.com/zo0r/react-native-push-notification + // Documentation Documentation https://github.com/invertase/notifee const isIOS = Platform.OS === "ios"; if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { return Promise.reject(new Error("Notifications module is not available in your app")); @@ -27,7 +27,7 @@ export async function CancelScheduledNotification(notificationId?: string): Prom return Promise.reject(new Error("Input parameter 'Notification id' is required")); } - PushNotification.cancelLocalNotification(notificationId); + notifee.cancelNotification(notificationId); return Promise.resolve(); // END USER CODE diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts b/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts index ba197fdfc..1249e9cad 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts @@ -6,7 +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 { NativeModules, Platform } from "react-native"; -import PushNotification from "react-native-push-notification"; +import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -17,13 +17,13 @@ import PushNotification from "react-native-push-notification"; */ export async function ClearAllDeliveredNotifications(): Promise { // BEGIN USER CODE - // Documentation https://github.com/zo0r/react-native-push-notification + // Documentation Documentation https://github.com/invertase/notifee const isIOS = Platform.OS === "ios"; if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { return Promise.reject(new Error("Notifications module is not available in your app")); } - PushNotification.removeAllDeliveredNotifications(); + notifee.cancelAllNotifications(); return Promise.resolve(); // END USER CODE diff --git a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts index de1077f8e..8700ceb21 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts @@ -5,8 +5,8 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 { NativeModules, Platform } from "react-native"; -import PushNotification, { PushNotificationObject } from "react-native-push-notification"; +import { Platform } from "react-native"; +import notifee, { AndroidChannel, AndroidImportance, Notification } from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -32,59 +32,56 @@ export async function DisplayNotification( actionGuid?: string ): Promise { // BEGIN USER CODE - // Documentation https://github.com/zo0r/react-native-push-notification - - const isIOS = Platform.OS === "ios"; - if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { - return Promise.reject(new Error("Notifications module is not available in your app")); - } - if (!body) { - return Promise.reject(new Error("Input parameter 'Body' is required")); + throw new Error("Input parameter 'Body' is required"); } - const notification = { message: body } as PushNotificationObject; + const channelId = "mendix-local-notifications"; + await createNotificationChannelIfNeeded(channelId); - if (!isIOS) { - const channelId = "mendix-local-notifications"; - const channelExists = await new Promise(resolve => - PushNotification.channelExists(channelId, (exists: boolean) => resolve(exists)) - ); - if (!channelExists) { - const channel = await new Promise(resolve => - PushNotification.createChannel( - { - channelId, - channelName: "Local notifications" - }, - created => resolve(created) - ) - ); - if (!channel) { - return Promise.reject(new Error("Could not create the local notifications channel")); - } + const notification: Notification = { + title: title || undefined, + body, + android: { + channelId, + // smallIcon: "ic_notification", + sound: playSound ? "default" : undefined + }, + ios: { + sound: playSound ? "default" : undefined } - notification.channelId = channelId; - } + }; - if (title) { - notification.title = title; + // Add subtitle for iOS (if provided) + if (subtitle && Platform.OS === "ios") { + notification.subtitle = subtitle; } - if (subtitle && !isIOS) { - notification.subText = subtitle; + // Add custom data (actionName and actionGuid) to the notification + if (actionName || actionGuid) { + notification.data = { + actionName: actionName || null, + guid: actionGuid || null + }; } - notification.playSound = !!playSound; + await notifee.displayNotification(notification); - if (actionName || actionGuid) { - notification.userInfo = { - actionName, - guid: actionGuid - }; + async function createNotificationChannelIfNeeded(channelId: string): Promise { + if (Platform.OS === "android") { + const channels = await notifee.getChannels(); + const isChannelExist = channels.some(c => c.name === channelId); + if (!isChannelExist) { + const channel: AndroidChannel = { + id: channelId, + name: "Local Notifications", + importance: AndroidImportance.HIGH + }; + await notifee.createChannel(channel); + } + } } - PushNotification.localNotification(notification); return Promise.resolve(); // END USER CODE } diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts index bf7e445ba..06511f340 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts @@ -5,9 +5,8 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 { NativeModules, Platform } from "react-native"; -import PushNotification, { PushNotificationScheduleObject } from "react-native-push-notification"; - +import { Platform } from "react-native"; +import notifee, { TimestampTrigger, TriggerType, AndroidChannel, AndroidImportance } from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -36,68 +35,62 @@ export async function ScheduleNotification( actionGuid?: string ): Promise { // BEGIN USER CODE - // Documentation https://github.com/zo0r/react-native-push-notification - - const isIOS = Platform.OS === "ios"; - if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { - return Promise.reject(new Error("Notifications module is not available in your app")); - } + const channelId = "mendix-local-notifications"; + await createNotificationChannelIfNeeded(channelId); if (!body) { - return Promise.reject(new Error("Input parameter 'Body' is required")); + throw new Error("Input parameter 'Body' is required"); } - const notification = { message: body } as PushNotificationScheduleObject; - const notificationIdNumber = Number(notificationId); - - if (!isIOS) { - const channelId = "mendix-local-notifications"; - const channelExists = await new Promise(resolve => - PushNotification.channelExists(channelId, (exists: boolean) => resolve(exists)) - ); - if (!channelExists) { - const channel = await new Promise(resolve => - PushNotification.createChannel( - { - channelId, - channelName: "Local notifications" - }, - created => resolve(created) - ) - ); - if (!channel) { - return Promise.reject(new Error("Could not create the local notifications channel")); - } - } - notification.channelId = channelId; + if (!date || !date.getTime()) { + throw new Error("Input parameter 'Date' is required and must be a valid Date object"); } - if (notificationIdNumber) { - notification.id = notificationIdNumber; - } + const trigger: TimestampTrigger = { + type: TriggerType.TIMESTAMP, + timestamp: date.getTime() + }; - if (title) { - notification.title = title; - } + const notification: any = { + id: notificationId || undefined, + title: title || undefined, + body, + android: { + channelId, + smallIcon: "ic_notification", + sound: playSound ? "default" : undefined + }, + ios: { + sound: !!playSound + } + }; - if (subtitle && !isIOS) { - notification.subText = subtitle; + if (subtitle && Platform.OS === "ios") { + notification.subtitle = subtitle; } - notification.playSound = !!playSound; - if (actionName || actionGuid) { - notification.userInfo = { - actionName, - guid: actionGuid + notification.data = { + actionName: actionName || null, + guid: actionGuid || null }; } - if (date && date.getTime()) { - notification.date = date; + async function createNotificationChannelIfNeeded(channelId: string): Promise { + if (Platform.OS === "android") { + const channels = await notifee.getChannels(); + const isChannelExist = channels.some(c => c.name === channelId); + if (!isChannelExist) { + const channel: AndroidChannel = { + id: channelId, + name: "Local Notifications", + importance: AndroidImportance.HIGH + }; + await notifee.createChannel(channel); + } + } } - PushNotification.localNotificationSchedule(notification); - return Promise.resolve(); + await notifee.createTriggerNotification(notification, trigger); // END USER CODE } diff --git a/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts b/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts index 30752a575..f6b98cbfd 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts @@ -7,7 +7,7 @@ // Other code you write will be lost the next time you deploy the project. import { Big } from "big.js"; import { NativeModules, Platform } from "react-native"; -import PushNotification from "react-native-push-notification"; +import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -18,7 +18,7 @@ import PushNotification from "react-native-push-notification"; */ export async function SetBadgeNumber(badgeNumber?: Big): Promise { // BEGIN USER CODE - // Documentation https://github.com/zo0r/react-native-push-notification + // Documentation Documentation https://github.com/invertase/notifee const isIOS = Platform.OS === "ios"; if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { @@ -33,7 +33,7 @@ export async function SetBadgeNumber(badgeNumber?: Big): Promise { return Promise.reject(new Error("Input parameter 'Badge number' should be zero or greater")); } - return PushNotification.setApplicationIconBadgeNumber(Number(badgeNumber)); + return notifee.setBadgeCount(badgeNumber as any as number); // END USER CODE } diff --git a/packages/pluggableWidgets/notifications-native/package.json b/packages/pluggableWidgets/notifications-native/package.json index adc991592..10f6732e4 100644 --- a/packages/pluggableWidgets/notifications-native/package.json +++ b/packages/pluggableWidgets/notifications-native/package.json @@ -19,9 +19,9 @@ }, "dependencies": { "@mendix/piw-utils-internal": "*", + "@notifee/react-native": "9.1.8", "@react-native-firebase/app": "17.3.0", - "@react-native-firebase/messaging": "17.3.0", - "react-native-push-notification": "8.1.1" + "@react-native-firebase/messaging": "17.3.0" }, "devDependencies": { "@mendix/pluggable-widgets-tools": "~10.0.1", diff --git a/packages/pluggableWidgets/notifications-native/src/Notifications.tsx b/packages/pluggableWidgets/notifications-native/src/Notifications.tsx index 9518cfdf9..1d71686f0 100644 --- a/packages/pluggableWidgets/notifications-native/src/Notifications.tsx +++ b/packages/pluggableWidgets/notifications-native/src/Notifications.tsx @@ -1,19 +1,14 @@ import messaging, { FirebaseMessagingTypes } from "@react-native-firebase/messaging"; -import PushNotification, { ReceivedNotification } from "react-native-push-notification"; import { executeAction } from "@mendix/piw-utils-internal"; import { useCallback, useEffect, useRef, useState } from "react"; import { Platform } from "react-native"; import { ActionValue, ValueStatus, Option } from "mendix"; import "@react-native-firebase/app"; +import notifee, { EventType } from "@notifee/react-native"; import { ActionsType, NotificationsProps } from "../typings/NotificationsProps"; // re-declare the library's type because: 1) it doesn't match library version 2) the definition file exports two symbols with same name. -interface IPushNotification extends ReceivedNotification { - title: string; - message: string; -} - interface ActionData { actionName?: string; guid?: string; @@ -110,22 +105,27 @@ export function Notifications(props: NotificationsProps): null { // wait for all used DynamicValues are available before configuring, else handleNotification is invoked while // properties in scope are loading. if (loadNotifications) { - PushNotification.configure({ - // called when user taps local notification - onNotification(notification: IPushNotification) { - const messageId = notification.data[Platform.OS === "ios" ? "gcm.message_id" : "google.message_id"]; + // Handle notifications when the app is in the foreground + notifee.onForegroundEvent(({ type, detail }) => { + if (type === EventType.PRESS) { + const notification = detail.notification; + if (notification === undefined || notification.data === undefined) { + console.log("notificaiton is not exist"); + return; + } + const messageId = + notification.data?.[Platform.OS === "ios" ? "gcm.message_id" : "google.message_id"]; handleNotification( { data: notification.data, title: notification.title, - body: notification.message, - subTitle: notification.subText + body: notification.body, + subTitle: notification.subtitle }, action => action.onOpen, - messageId + messageId as any ); - }, - requestPermissions: Platform.OS === "ios" + } }); } }, [loadNotifications, handleNotification]); diff --git a/yarn.lock b/yarn.lock index 8797fc0b5..dc4054f35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2587,6 +2587,15 @@ __metadata: languageName: node linkType: hard +"@notifee/react-native@npm:9.1.8": + version: 9.1.8 + resolution: "@notifee/react-native@npm:9.1.8" + peerDependencies: + react-native: "*" + checksum: 10/7c5237fba99906d8da02146afbfe8ff6de9f4047eecd806dea889bfd76b1cfe7ad3c181881bf2729aa348b83e035f4d02cfc3ac8eb8c4ba3a4415b445b439c38 + languageName: node + linkType: hard + "@npmcli/agent@npm:^3.0.0": version: 3.0.0 resolution: "@npmcli/agent@npm:3.0.0" @@ -2986,18 +2995,6 @@ __metadata: languageName: node linkType: hard -"@react-native-community/push-notification-ios@npm:1.10.1": - version: 1.10.1 - resolution: "@react-native-community/push-notification-ios@npm:1.10.1" - dependencies: - invariant: "npm:^2.2.4" - peerDependencies: - react: ">=16.6.3" - react-native: ">=0.58.4" - checksum: 10/5b02066ebad4200957bbb60634d42f4a2ea647d9d84d69adcf6fa71acf72063110d2f7b7b1e45d4153d94a3592806f5de9626fb33897707197c03a14ea299a55 - languageName: node - linkType: hard - "@react-native-firebase/app@npm:17.3.0": version: 17.3.0 resolution: "@react-native-firebase/app@npm:17.3.0" @@ -3421,7 +3418,7 @@ __metadata: languageName: node linkType: hard -"@swan-io/react-native-browser@npm:^0.4.1": +"@swan-io/react-native-browser@npm:0.4.1": version: 0.4.1 resolution: "@swan-io/react-native-browser@npm:0.4.1" peerDependencies: @@ -4016,13 +4013,6 @@ __metadata: languageName: node linkType: hard -"@types/react-native-push-notification@npm:8.1.1": - version: 8.1.1 - resolution: "@types/react-native-push-notification@npm:8.1.1" - checksum: 10/67606daf7cd38e1e8d7d82dee49741ebe8cf59cd2002579ba287ce9e98c461d11f84cf746f90cbbb7884701fe9bc758673ef2d9559cb0c73ca82307952558199 - languageName: node - linkType: hard - "@types/react-native-snap-carousel@npm:^3.7.4": version: 3.8.11 resolution: "@types/react-native-snap-carousel@npm:3.8.11" @@ -12128,12 +12118,11 @@ __metadata: resolution: "mobile-resources-native@workspace:packages/jsActions/mobile-resources-native" dependencies: "@mendix/pluggable-widgets-tools": "npm:^10.0.1" + "@notifee/react-native": "npm:9.1.8" "@react-native-camera-roll/camera-roll": "npm:7.4.0" - "@react-native-community/push-notification-ios": "npm:1.10.1" "@react-native-firebase/messaging": "npm:17.3.0" - "@swan-io/react-native-browser": "npm:^0.4.1" + "@swan-io/react-native-browser": "npm:0.4.1" "@types/querystringify": "npm:^2.0.0" - "@types/react-native-push-notification": "npm:8.1.1" "@types/url-parse": "npm:^1.4.3" eslint: "npm:^7.32.0" fbjs: "npm:3.0.4" @@ -12145,7 +12134,6 @@ __metadata: react-native-image-picker: "npm:7.2.3" react-native-localize: "npm:3.2.1" react-native-permissions: "npm:4.1.5" - react-native-push-notification: "npm:8.1.1" react-native-schedule-exact-alarm-permission: "npm:^0.1.3" react-native-sound: "npm:0.11.0" react-native-touch-id: "npm:4.4.1" @@ -12500,10 +12488,10 @@ __metadata: dependencies: "@mendix/piw-utils-internal": "npm:*" "@mendix/pluggable-widgets-tools": "npm:~10.0.1" + "@notifee/react-native": "npm:9.1.8" "@react-native-firebase/app": "npm:17.3.0" "@react-native-firebase/messaging": "npm:17.3.0" eslint: "npm:^7.32.0" - react-native-push-notification: "npm:8.1.1" languageName: unknown linkType: soft @@ -14270,16 +14258,6 @@ __metadata: languageName: node linkType: hard -"react-native-push-notification@npm:8.1.1": - version: 8.1.1 - resolution: "react-native-push-notification@npm:8.1.1" - peerDependencies: - "@react-native-community/push-notification-ios": ^1.10.1 - react-native: ">=0.33" - checksum: 10/c03b517743b1a5bf022e7c0c0ee2001bad9478d384c6e05ec926b81ca21125dd72ccdb28930386e8bb2b26701369921e764e8a196ed113f208d9ef37c5c6d9c7 - languageName: node - linkType: hard - "react-native-qrcode-svg@npm:6.0.6": version: 6.0.6 resolution: "react-native-qrcode-svg@npm:6.0.6" From d0bdf6fba1233b45afee117532c3eb30a992d955 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 09:54:33 +0200 Subject: [PATCH 02/23] migrate react-native-fast-image to react-native-turbo-image --- .../image-native/package.json | 2 +- .../src/components/ImageIconSVG.tsx | 8 +- .../__snapshots__/Image.spec.tsx.snap | 176 +++++++----------- yarn.lock | 22 +-- 4 files changed, 84 insertions(+), 124 deletions(-) diff --git a/packages/pluggableWidgets/image-native/package.json b/packages/pluggableWidgets/image-native/package.json index f3ebd6e22..d2439a461 100644 --- a/packages/pluggableWidgets/image-native/package.json +++ b/packages/pluggableWidgets/image-native/package.json @@ -30,8 +30,8 @@ "dependencies": { "@mendix/piw-native-utils-internal": "*", "@mendix/piw-utils-internal": "*", - "react-native-fast-image": "8.3.2", "react-native-svg": "15.7.1", + "react-native-turbo-image": "^1.22.3", "react-native-vector-icons": "10.2.0" }, "devDependencies": { diff --git a/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx b/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx index c1470bea6..8914e6020 100644 --- a/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx +++ b/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx @@ -1,12 +1,12 @@ import { createElement, FunctionComponent, Fragment, useCallback } from "react"; import { View } from "react-native"; import { SvgUri, SvgXml } from "react-native-svg"; -import FastImageComponent, { Source } from "react-native-fast-image"; import { extractStyles } from "@mendix/pluggable-widgets-tools"; import { CustomImageProps, GlyphIcon } from "../utils/imageUtils"; import { GlyphIcon as GlyphIconComponent } from "./fonts/font"; import { ResizeModeEnum } from "../../typings/ImageProps"; import { getPositionFromSVG } from "../utils/svgUtils"; +import TurboImage, { Source } from "react-native-turbo-image"; export interface DimensionsType { width?: number; @@ -65,9 +65,9 @@ export const ImageIconSVG: FunctionComponent = props => { if (image && (type === "staticImage" || type === "dynamicImage")) { return ( - - - - - - - - - - - - - - - - - - - - - =0.60.0" - checksum: 10/398def3b64af545cca5380087637026e873216c3f009146cf7da8bdb44ab9aca38d17b38cbf268c50125a4b282f67a7ae861531b5ee03832962e71efdf11279b - languageName: node - linkType: hard - "react-native-file-viewer@npm:2.1.5": version: 2.1.5 resolution: "react-native-file-viewer@npm:2.1.5" @@ -14383,6 +14373,16 @@ __metadata: languageName: node linkType: hard +"react-native-turbo-image@npm:^1.22.3": + version: 1.22.3 + resolution: "react-native-turbo-image@npm:1.22.3" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10/b09e4bbf95de81dee9c5929d87a216167f5d7bef0b9c0e898e2fe574f00b57437224eb32ea8380f75d9b4e5108ec2b6eac3830cde1ce9059feea66517e46c3e0 + languageName: node + linkType: hard + "react-native-vector-icons@npm:10.2.0": version: 10.2.0 resolution: "react-native-vector-icons@npm:10.2.0" From d645545e70649ea057881272eed13923e5789426 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 10:34:23 +0200 Subject: [PATCH 03/23] changelog and version update --- .../pluggableWidgets/background-gradient-native/package.json | 4 ++-- .../background-gradient-native/src/package.xml | 2 +- packages/pluggableWidgets/image-native/CHANGELOG.md | 2 ++ packages/pluggableWidgets/image-native/package.json | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/pluggableWidgets/background-gradient-native/package.json b/packages/pluggableWidgets/background-gradient-native/package.json index 533e4db62..b9a726cf2 100644 --- a/packages/pluggableWidgets/background-gradient-native/package.json +++ b/packages/pluggableWidgets/background-gradient-native/package.json @@ -1,7 +1,7 @@ { "name": "background-gradient-native", "widgetName": "BackgroundGradient", - "version": "2.1.0", + "version": "3.0.0", "repository": { "type": "git", "url": "https://github.com/mendix/native-widgets.git" @@ -30,6 +30,6 @@ }, "dependencies": { "@mendix/piw-utils-internal": "*", - "react-native-linear-gradient": "2.5.6" + "expo-linear-gradient": "14.0.2" } } diff --git a/packages/pluggableWidgets/background-gradient-native/src/package.xml b/packages/pluggableWidgets/background-gradient-native/src/package.xml index f8c80fdc7..463ed8e10 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/package.xml +++ b/packages/pluggableWidgets/background-gradient-native/src/package.xml @@ -1,6 +1,6 @@ - + diff --git a/packages/pluggableWidgets/image-native/CHANGELOG.md b/packages/pluggableWidgets/image-native/CHANGELOG.md index 30a9b2cd3..14831606c 100644 --- a/packages/pluggableWidgets/image-native/CHANGELOG.md +++ b/packages/pluggableWidgets/image-native/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +- Migrated react-native-fast-image to react-native-turbo-image to support react-native new architecture. + ## [3.0.0] - 2024-12-3 ### Changed diff --git a/packages/pluggableWidgets/image-native/package.json b/packages/pluggableWidgets/image-native/package.json index d2439a461..cad71b027 100644 --- a/packages/pluggableWidgets/image-native/package.json +++ b/packages/pluggableWidgets/image-native/package.json @@ -1,7 +1,7 @@ { "name": "image-native", "widgetName": "Image", - "version": "3.0.0", + "version": "3.1.0", "description": "Display an image and enlarge it on click", "copyright": "© Mendix Technology BV 2022. All rights reserved.", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "@mendix/piw-native-utils-internal": "*", "@mendix/piw-utils-internal": "*", "react-native-svg": "15.7.1", - "react-native-turbo-image": "^1.22.3", + "react-native-turbo-image": "1.22.3", "react-native-vector-icons": "10.2.0" }, "devDependencies": { From aff20a4cc8c11e6cadd26172ff32e51f2826cca1 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 10:34:37 +0200 Subject: [PATCH 04/23] changelog --- .../pluggableWidgets/background-gradient-native/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md b/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md index c48f6cee3..87fd147dc 100644 --- a/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md +++ b/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +- Migrated react-native-linear-gradient to expo-linear-gradient to support react-native new architecture. + ## [2.1.0] - 2024-12-3 ### Changed From e91c856f079192e4e870d6822865d6540b0b2c05 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 10:35:00 +0200 Subject: [PATCH 05/23] migrated react-native-linear-gradient to expo-linear-gradient --- .../src/BackgroundGradient.tsx | 43 +++++++++++-------- .../image-native/src/package.xml | 2 +- yarn.lock | 26 +++++------ 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx b/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx index eb509210c..7aff8f811 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx +++ b/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx @@ -1,6 +1,6 @@ -import { ReactElement, createElement } from "react"; -import { Pressable, NativeModules, Alert } from "react-native"; -import LinearGradient from "react-native-linear-gradient"; +import { createElement, ReactElement } from "react"; +import { Pressable, View, StyleSheet } from "react-native"; +import { LinearGradient } from "expo-linear-gradient"; import { all } from "deepmerge"; import { executeAction } from "@mendix/piw-utils-internal"; import defaultStyle, { CustomStyle } from "./ui/Styles"; @@ -19,7 +19,6 @@ const opacityValidation = (opacity: number | undefined): number => { if (opacityVal < 0 || opacityVal > 100) { console.warn("Opacity must be between 0 and 100."); } - return opacityVal / 100; }; @@ -31,15 +30,20 @@ const angleValidation = (angle: number | undefined): number => { if (isNaN(angleVal)) { throw new Error("Angle must be a number."); } - return angleVal; }; -export function BackgroundGradient({ name, colorList, content, onClick, style }: props): ReactElement { - if (!("BVLinearGradient" in NativeModules.UIManager)) { - Alert.alert("", "The widget 'Background gradient' requires an updated 'Make It Native 9' application"); - } +// Convert angle to Expo's LinearGradient start/end points +const angleToCoords = (angle: number) => { + const radians = (angle * Math.PI) / 180; + const x = Math.cos(radians); + const y = Math.sin(radians); + const start = { x: 0.5 - x / 2, y: 0.5 - y / 2 }; + const end = { x: 0.5 + x / 2, y: 0.5 + y / 2 }; + return { start, end }; +}; +export function BackgroundGradient({ name, colorList, content, onClick, style }: props): ReactElement { const styles = all([defaultStyle, ...style]); const angle = angleValidation(styles.angle); const opacity = opacityValidation(styles.opacity); @@ -52,28 +56,31 @@ export function BackgroundGradient({ name, colorList, content, onClick, style }: throw new Error("The color list could not be empty."); } - // checking if the color list only have one color item , then we should duplicate it. one color list throws an exception on android. if (sortedColorList.length === 1) { sortedColorList = [...sortedColorList, ...sortedColorList]; } - const colors = sortedColorList.map(colorsObject => colorsObject.color.toLowerCase()); - const offsets = sortedColorList.map(colorsObject => Number(colorsObject.offset)); + const colors = sortedColorList.map(c => c.color.toLowerCase()) as [string, string, ...string[]]; + const locations = sortedColorList.map(c => Number(c.offset)) as [number, number, ...number[]]; + const { start, end } = angleToCoords(angle); return ( { - executeAction(onClick); - }} + onPress={() => executeAction(onClick)} testID={name} style={({ pressed }) => ({ flex: styles.container.flex, opacity: onClick?.canExecute && pressed ? opacity * 0.3 : opacity })} > - - {content} - + + {content} ); } diff --git a/packages/pluggableWidgets/image-native/src/package.xml b/packages/pluggableWidgets/image-native/src/package.xml index 9012cd112..651338b87 100644 --- a/packages/pluggableWidgets/image-native/src/package.xml +++ b/packages/pluggableWidgets/image-native/src/package.xml @@ -1,6 +1,6 @@ - + diff --git a/yarn.lock b/yarn.lock index 51e31edcd..a84baeba8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5137,7 +5137,7 @@ __metadata: "@mendix/piw-utils-internal": "npm:*" "@mendix/pluggable-widgets-tools": "npm:~10.0.1" eslint: "npm:^7.32.0" - react-native-linear-gradient: "npm:2.5.6" + expo-linear-gradient: "npm:14.0.2" languageName: unknown linkType: soft @@ -7781,6 +7781,17 @@ __metadata: languageName: node linkType: hard +"expo-linear-gradient@npm:14.0.2": + version: 14.0.2 + resolution: "expo-linear-gradient@npm:14.0.2" + peerDependencies: + expo: "*" + react: "*" + react-native: "*" + checksum: 10/73471a435fa720137c5bb16ddc699c64181101db081cd4ff892b383e9f047db56039fd1235f3570dd2fccd099214230f98405963c9c8afc32891c43eabae2c60 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.2 resolution: "exponential-backoff@npm:3.1.2" @@ -8947,7 +8958,7 @@ __metadata: "@mendix/pluggable-widgets-tools": "npm:~10.0.1" eslint: "npm:^7.32.0" react-native-svg: "npm:15.7.1" - react-native-turbo-image: "npm:^1.22.3" + react-native-turbo-image: "npm:1.22.3" react-native-vector-icons: "npm:10.2.0" languageName: unknown linkType: soft @@ -14161,15 +14172,6 @@ __metadata: languageName: node linkType: hard -"react-native-linear-gradient@npm:2.5.6": - version: 2.5.6 - resolution: "react-native-linear-gradient@npm:2.5.6" - peerDependencies: - react-native: ">=0.55" - checksum: 10/a3ab9806b99c68b697c1240a288117a48ea6e070f515fd17d39935d24fb046f0a99964158b995f3daecfbbcad16dfb63f13b3840fa830d36d7c47563aa563a08 - languageName: node - linkType: hard - "react-native-localize@npm:3.2.1": version: 3.2.1 resolution: "react-native-localize@npm:3.2.1" @@ -14373,7 +14375,7 @@ __metadata: languageName: node linkType: hard -"react-native-turbo-image@npm:^1.22.3": +"react-native-turbo-image@npm:1.22.3": version: 1.22.3 resolution: "react-native-turbo-image@npm:1.22.3" peerDependencies: From 33b1abcda3bfc60fc2e0942fb8a79d790b9b2db1 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 22:06:42 +0200 Subject: [PATCH 06/23] revert expo linear gradient --- .../background-gradient-native/CHANGELOG.md | 2 +- .../background-gradient-native/package.json | 4 +- .../src/BackgroundGradient.tsx | 43 ++++++++----------- .../src/package.xml | 2 +- yarn.lock | 23 +++++----- 5 files changed, 33 insertions(+), 41 deletions(-) diff --git a/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md b/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md index 87fd147dc..1eb9cc7e1 100644 --- a/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md +++ b/packages/pluggableWidgets/background-gradient-native/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] -- Migrated react-native-linear-gradient to expo-linear-gradient to support react-native new architecture. +- Updated react-native-linear-gradient to latest version. ## [2.1.0] - 2024-12-3 diff --git a/packages/pluggableWidgets/background-gradient-native/package.json b/packages/pluggableWidgets/background-gradient-native/package.json index b9a726cf2..cc0f128b4 100644 --- a/packages/pluggableWidgets/background-gradient-native/package.json +++ b/packages/pluggableWidgets/background-gradient-native/package.json @@ -1,7 +1,7 @@ { "name": "background-gradient-native", "widgetName": "BackgroundGradient", - "version": "3.0.0", + "version": "2.2.0", "repository": { "type": "git", "url": "https://github.com/mendix/native-widgets.git" @@ -30,6 +30,6 @@ }, "dependencies": { "@mendix/piw-utils-internal": "*", - "expo-linear-gradient": "14.0.2" + "react-native-linear-gradient": "3.0.0-alpha.1" } } diff --git a/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx b/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx index 7aff8f811..839af075d 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx +++ b/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx @@ -1,6 +1,6 @@ -import { createElement, ReactElement } from "react"; -import { Pressable, View, StyleSheet } from "react-native"; -import { LinearGradient } from "expo-linear-gradient"; +import { ReactElement, createElement } from "react"; +import { Pressable, NativeModules, Alert } from "react-native"; +import LinearGradient from "react-native-linear-gradient"; import { all } from "deepmerge"; import { executeAction } from "@mendix/piw-utils-internal"; import defaultStyle, { CustomStyle } from "./ui/Styles"; @@ -19,6 +19,7 @@ const opacityValidation = (opacity: number | undefined): number => { if (opacityVal < 0 || opacityVal > 100) { console.warn("Opacity must be between 0 and 100."); } + return opacityVal / 100; }; @@ -30,20 +31,15 @@ const angleValidation = (angle: number | undefined): number => { if (isNaN(angleVal)) { throw new Error("Angle must be a number."); } - return angleVal; -}; -// Convert angle to Expo's LinearGradient start/end points -const angleToCoords = (angle: number) => { - const radians = (angle * Math.PI) / 180; - const x = Math.cos(radians); - const y = Math.sin(radians); - const start = { x: 0.5 - x / 2, y: 0.5 - y / 2 }; - const end = { x: 0.5 + x / 2, y: 0.5 + y / 2 }; - return { start, end }; + return angleVal; }; export function BackgroundGradient({ name, colorList, content, onClick, style }: props): ReactElement { + if (!("BVLinearGradient" in NativeModules.UIManager)) { + Alert.alert("", "The widget 'Background gradient' requires an updated 'Make It Native 9' application"); + } + const styles = all([defaultStyle, ...style]); const angle = angleValidation(styles.angle); const opacity = opacityValidation(styles.opacity); @@ -56,31 +52,28 @@ export function BackgroundGradient({ name, colorList, content, onClick, style }: throw new Error("The color list could not be empty."); } + // checking if the color list only have one color item , then we should duplicate it. one color list throws an exception on android. if (sortedColorList.length === 1) { sortedColorList = [...sortedColorList, ...sortedColorList]; } - const colors = sortedColorList.map(c => c.color.toLowerCase()) as [string, string, ...string[]]; - const locations = sortedColorList.map(c => Number(c.offset)) as [number, number, ...number[]]; - const { start, end } = angleToCoords(angle); + const colors = sortedColorList.map(colorsObject => colorsObject.color.toLowerCase()); + const offsets = sortedColorList.map(colorsObject => Number(colorsObject.offset)); return ( executeAction(onClick)} + onPress={() => { + executeAction(onClick); + }} testID={name} style={({ pressed }) => ({ flex: styles.container.flex, opacity: onClick?.canExecute && pressed ? opacity * 0.3 : opacity })} > - - {content} + + {content} + ); } diff --git a/packages/pluggableWidgets/background-gradient-native/src/package.xml b/packages/pluggableWidgets/background-gradient-native/src/package.xml index 463ed8e10..7ae868b45 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/package.xml +++ b/packages/pluggableWidgets/background-gradient-native/src/package.xml @@ -1,6 +1,6 @@ - + diff --git a/yarn.lock b/yarn.lock index a84baeba8..e9b4560c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5137,7 +5137,7 @@ __metadata: "@mendix/piw-utils-internal": "npm:*" "@mendix/pluggable-widgets-tools": "npm:~10.0.1" eslint: "npm:^7.32.0" - expo-linear-gradient: "npm:14.0.2" + react-native-linear-gradient: "npm:3.0.0-alpha.1" languageName: unknown linkType: soft @@ -7781,17 +7781,6 @@ __metadata: languageName: node linkType: hard -"expo-linear-gradient@npm:14.0.2": - version: 14.0.2 - resolution: "expo-linear-gradient@npm:14.0.2" - peerDependencies: - expo: "*" - react: "*" - react-native: "*" - checksum: 10/73471a435fa720137c5bb16ddc699c64181101db081cd4ff892b383e9f047db56039fd1235f3570dd2fccd099214230f98405963c9c8afc32891c43eabae2c60 - languageName: node - linkType: hard - "exponential-backoff@npm:^3.1.1": version: 3.1.2 resolution: "exponential-backoff@npm:3.1.2" @@ -14172,6 +14161,16 @@ __metadata: languageName: node linkType: hard +"react-native-linear-gradient@npm:3.0.0-alpha.1": + version: 3.0.0-alpha.1 + resolution: "react-native-linear-gradient@npm:3.0.0-alpha.1" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10/95eef8707bf8c38b16d265c46d945ee9c10a27a0da8b64bdf00ea62d905e303d30e06c61a065f85aa27bbfa3faa124c172e8f95335363fd6cb089f939f62ba85 + languageName: node + linkType: hard + "react-native-localize@npm:3.2.1": version: 3.2.1 resolution: "react-native-localize@npm:3.2.1" From cc4f2a7549d62affeaa360038358a85adc12e3d3 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 22:36:29 +0200 Subject: [PATCH 07/23] updated react-native-device-info to latest version. --- configs/e2e/native_dependencies.json | 2 +- packages/jsActions/mobile-resources-native/package.json | 2 +- packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md | 2 ++ packages/pluggableWidgets/bottom-sheet-native/package.json | 4 ++-- packages/pluggableWidgets/bottom-sheet-native/src/package.xml | 2 +- packages/pluggableWidgets/gallery-native/CHANGELOG.md | 2 ++ packages/pluggableWidgets/gallery-native/package.json | 4 ++-- packages/pluggableWidgets/gallery-native/src/package.xml | 2 +- packages/pluggableWidgets/intro-screen-native/CHANGELOG.md | 2 ++ packages/pluggableWidgets/intro-screen-native/package.json | 2 +- 10 files changed, 15 insertions(+), 9 deletions(-) diff --git a/configs/e2e/native_dependencies.json b/configs/e2e/native_dependencies.json index e2f04ed89..c2b28fe46 100644 --- a/configs/e2e/native_dependencies.json +++ b/configs/e2e/native_dependencies.json @@ -1,7 +1,7 @@ { "react-native-maps": "1.14.0", "react-native-geocoder": "0.5.0", - "react-native-device-info": "13.0.0", + "react-native-device-info": "14.0.4", "react-native-action-button": "2.8.5", "react-native-material-menu": "1.2.0", "react-native-linear-gradient": "2.5.6", diff --git a/packages/jsActions/mobile-resources-native/package.json b/packages/jsActions/mobile-resources-native/package.json index ac8cef09a..697657356 100644 --- a/packages/jsActions/mobile-resources-native/package.json +++ b/packages/jsActions/mobile-resources-native/package.json @@ -33,7 +33,7 @@ "fbjs": "3.0.4", "mime": "3.0.0", "react-native-blob-util": "0.21.2", - "react-native-device-info": "13.0.0", + "react-native-device-info": "14.0.4", "react-native-file-viewer": "2.1.5", "react-native-image-picker": "7.2.3", "react-native-localize": "3.2.1", diff --git a/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md b/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md index 8bb1cfe2e..ab4e97380 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md +++ b/packages/pluggableWidgets/bottom-sheet-native/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +- Updated react-native-device-info to latest version. + ## [5.0.0] - 2025-3-31 ### Changed diff --git a/packages/pluggableWidgets/bottom-sheet-native/package.json b/packages/pluggableWidgets/bottom-sheet-native/package.json index 0483b66c8..b741239b7 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/package.json +++ b/packages/pluggableWidgets/bottom-sheet-native/package.json @@ -1,7 +1,7 @@ { "name": "bottom-sheet-native", "widgetName": "BottomSheet", - "version": "5.0.0", + "version": "5.0.1", "license": "Apache-2.0", "repository": { "type": "git", @@ -23,7 +23,7 @@ "@mendix/piw-native-utils-internal": "*", "@mendix/piw-utils-internal": "*", "@shopify/flash-list": "1.7.3", - "react-native-device-info": "13.0.0", + "react-native-device-info": "14.0.4", "react-native-gesture-handler": "2.24.0", "react-native-reanimated": "3.16.1" }, diff --git a/packages/pluggableWidgets/bottom-sheet-native/src/package.xml b/packages/pluggableWidgets/bottom-sheet-native/src/package.xml index c92801bb3..c4f1be9f3 100644 --- a/packages/pluggableWidgets/bottom-sheet-native/src/package.xml +++ b/packages/pluggableWidgets/bottom-sheet-native/src/package.xml @@ -1,6 +1,6 @@ - + diff --git a/packages/pluggableWidgets/gallery-native/CHANGELOG.md b/packages/pluggableWidgets/gallery-native/CHANGELOG.md index a43eb8433..b02304cc2 100644 --- a/packages/pluggableWidgets/gallery-native/CHANGELOG.md +++ b/packages/pluggableWidgets/gallery-native/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [2.0.0] - 2024-12-3 +- Updated react-native-device-info to latest version. + ### Changed - Updated @mendix/pluggable-widgets-tools from version v9.0.0 to v10.15.0. diff --git a/packages/pluggableWidgets/gallery-native/package.json b/packages/pluggableWidgets/gallery-native/package.json index 9cde4741e..8da5bc9d7 100644 --- a/packages/pluggableWidgets/gallery-native/package.json +++ b/packages/pluggableWidgets/gallery-native/package.json @@ -1,7 +1,7 @@ { "name": "gallery-native", "widgetName": "Gallery", - "version": "2.0.0", + "version": "2.0.1", "description": "A flexible gallery widget that renders columns, rows and layouts.", "copyright": "© Mendix Technology BV 2022. All rights reserved.", "license": "Apache-2.0", @@ -29,7 +29,7 @@ }, "dependencies": { "@mendix/piw-utils-internal": "*", - "react-native-device-info": "13.0.0" + "react-native-device-info": "14.0.4" }, "devDependencies": { "@mendix/pluggable-widgets-tools": "~10.0.1", diff --git a/packages/pluggableWidgets/gallery-native/src/package.xml b/packages/pluggableWidgets/gallery-native/src/package.xml index eb13e1580..80b03d697 100644 --- a/packages/pluggableWidgets/gallery-native/src/package.xml +++ b/packages/pluggableWidgets/gallery-native/src/package.xml @@ -1,6 +1,6 @@ - + diff --git a/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md b/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md index fd233833f..9dbb2a298 100644 --- a/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md +++ b/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md @@ -12,6 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [4.0.0] - 2024-12-3 +- Updated react-native-device-info to latest version. + ### Changed - Updated @mendix/pluggable-widgets-tools from version v9.0.0 to v10.15.0. diff --git a/packages/pluggableWidgets/intro-screen-native/package.json b/packages/pluggableWidgets/intro-screen-native/package.json index 767d90b26..847673857 100644 --- a/packages/pluggableWidgets/intro-screen-native/package.json +++ b/packages/pluggableWidgets/intro-screen-native/package.json @@ -28,7 +28,7 @@ "@mendix/piw-native-utils-internal": "*", "@mendix/piw-utils-internal": "*", "@react-native-async-storage/async-storage": "2.0.0", - "react-native-device-info": "13.0.0" + "react-native-device-info": "14.0.4" }, "devDependencies": { "@mendix/pluggable-widgets-tools": "~10.0.1", From e420914777bf055e786946a56eac8b15e14843b8 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 23:01:00 +0200 Subject: [PATCH 08/23] migrate react-native-touch-id to react-native-biometrics --- .../mobile-resources-native/package.json | 2 +- .../authentication/BiometricAuthentication.ts | 9 +- .../IsBiometricAuthenticationSupported.ts | 9 +- .../typings/TouchID.d.ts | 116 ------------------ yarn.lock | 34 ++--- 5 files changed, 31 insertions(+), 139 deletions(-) delete mode 100644 packages/jsActions/mobile-resources-native/typings/TouchID.d.ts diff --git a/packages/jsActions/mobile-resources-native/package.json b/packages/jsActions/mobile-resources-native/package.json index 697657356..dfe794f57 100644 --- a/packages/jsActions/mobile-resources-native/package.json +++ b/packages/jsActions/mobile-resources-native/package.json @@ -32,6 +32,7 @@ "@swan-io/react-native-browser": "0.4.1", "fbjs": "3.0.4", "mime": "3.0.0", + "react-native-biometrics": "3.0.1", "react-native-blob-util": "0.21.2", "react-native-device-info": "14.0.4", "react-native-file-viewer": "2.1.5", @@ -40,7 +41,6 @@ "react-native-permissions": "4.1.5", "react-native-schedule-exact-alarm-permission": "^0.1.3", "react-native-sound": "0.11.0", - "react-native-touch-id": "4.4.1", "url-parse": "^1.4.7" }, "devDependencies": { diff --git a/packages/jsActions/mobile-resources-native/src/authentication/BiometricAuthentication.ts b/packages/jsActions/mobile-resources-native/src/authentication/BiometricAuthentication.ts index c9b62e70e..d44e79e70 100644 --- a/packages/jsActions/mobile-resources-native/src/authentication/BiometricAuthentication.ts +++ b/packages/jsActions/mobile-resources-native/src/authentication/BiometricAuthentication.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 TouchID from "react-native-touch-id"; +import ReactNativeBiometrics from "react-native-biometrics"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -16,9 +16,12 @@ import TouchID from "react-native-touch-id"; */ export async function BiometricAuthentication(reason?: string): Promise { // BEGIN USER CODE - // Documentation https://github.com/naoufal/react-native-touch-id + // Documentation https://github.com/smallcase/react-native-simple-biometrics - return TouchID.authenticate(reason) + const rnBiometrics = new ReactNativeBiometrics(); + + return rnBiometrics + .simplePrompt({ promptMessage: reason ?? "" }) .then(() => true) .catch(() => false); diff --git a/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts b/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts index 3387850b4..0fb5a7e07 100644 --- a/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts +++ b/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 TouchID from "react-native-touch-id"; +import ReactNativeBiometrics from "react-native-biometrics"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -15,9 +15,12 @@ import TouchID from "react-native-touch-id"; */ export async function IsBiometricAuthenticationSupported(): Promise { // BEGIN USER CODE - // Documentation https://github.com/naoufal/react-native-touch-id + // Documentation https://github.com/smallcase/react-native-simple-biometrics - return TouchID.isSupported() + const rnBiometrics = new ReactNativeBiometrics(); + + return rnBiometrics + .isSensorAvailable() .then(() => true) .catch(() => false); diff --git a/packages/jsActions/mobile-resources-native/typings/TouchID.d.ts b/packages/jsActions/mobile-resources-native/typings/TouchID.d.ts deleted file mode 100644 index 8aab38c7a..000000000 --- a/packages/jsActions/mobile-resources-native/typings/TouchID.d.ts +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Source: https://github.com/naoufal/react-native-touch-id/blob/master/index.d.ts - * (Modified) - * - * Copyright (c) 2015, Naoufal Kadhom - * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -declare module "react-native-touch-id" { - /** - * The supported biometry type - */ - type BiometryType = "FaceID" | "TouchID"; - - /** - * Base config to pass to `TouchID.isSupported` and `TouchID.authenticate` - */ - interface IsSupportedConfig { - /** - * Return unified error messages - */ - unifiedErrors?: boolean; - } - - /** - * Authentication config - */ - export interface AuthenticateConfig extends IsSupportedConfig { - /** - * **Android only** - Title of confirmation dialog - */ - title?: string; - /** - * **Android only** - Color of fingerprint image - */ - imageColor?: string; - /** - * **Android only** - Color of fingerprint image after failed attempt - */ - imageErrorColor?: string; - /** - * **Android only** - Text shown next to the fingerprint image - */ - sensorDescription?: string; - /** - * **Android only** - Text shown next to the fingerprint image after failed attempt - */ - sensorErrorDescription?: string; - /** - * **Android only** - Cancel button text - */ - cancelText?: string; - /** - * **iOS only** - By default specified 'Show Password' label. If set to empty string label is invisible. - */ - fallbackLabel?: string; - /** - * **iOS only** - By default set to false. If set to true, will allow use of keypad passcode. - */ - passcodeFallback?: boolean; - } - /** - * `isSupported` error code - */ - type IsSupportedErrorCode = "NOT_SUPPORTED" | "NOT_AVAILABLE" | "NOT_PRESENT" | "NOT_ENROLLED"; - - /** - * `authenticate` error code - */ - type AuthenticateErrorCode = - | IsSupportedErrorCode - | "AUTHENTICATION_FAILED" - | "USER_CANCELED" - | "SYSTEM_CANCELED" - | "TIMEOUT" - | "LOCKOUT" - | "LOCKOUT_PERMANENT" - | "PROCESSING_ERROR" - | "USER_FALLBACK" - | "UNKNOWN_ERROR"; - - /** - * Error returned from `authenticate` - */ - export interface AuthenticationError { - name: "TouchIDError"; - message: string; - code: AuthenticateErrorCode; - details: string; - } - /** - * Error returned from `isSupported` - */ - export interface IsSupportedError { - name: "TouchIDError"; - message: string; - code: IsSupportedErrorCode; - details: string; - } - - const TouchID: { - /** - * - * @param reason String that provides a clear reason for requesting authentication. - * @param config Configuration object for more detailed dialog setup - */ - authenticate(reason?: string, config?: AuthenticateConfig): Promise; - /** - * - * @param config - Returns a `Promise` that rejects if TouchID is not supported. On iOS resolves with a `biometryType` `String` of `FaceID` or `TouchID` - */ - isSupported(config?: IsSupportedConfig): Promise; - }; - export default TouchID; -} diff --git a/yarn.lock b/yarn.lock index e9b4560c3..683d42fab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5274,7 +5274,7 @@ __metadata: "@types/react-native-actionsheet": "npm:^2.4.1" "@types/react-native-modal": "npm:^4.1.1" eslint: "npm:^7.32.0" - react-native-device-info: "npm:13.0.0" + react-native-device-info: "npm:14.0.4" react-native-gesture-handler: "npm:2.24.0" react-native-reanimated: "npm:3.16.1" languageName: unknown @@ -8280,7 +8280,7 @@ __metadata: "@mendix/piw-utils-internal": "npm:*" "@mendix/pluggable-widgets-tools": "npm:~10.0.1" eslint: "npm:^7.32.0" - react-native-device-info: "npm:13.0.0" + react-native-device-info: "npm:14.0.4" languageName: unknown linkType: soft @@ -9101,7 +9101,7 @@ __metadata: "@mendix/pluggable-widgets-tools": "npm:~10.0.1" "@react-native-async-storage/async-storage": "npm:2.0.0" eslint: "npm:^7.32.0" - react-native-device-info: "npm:13.0.0" + react-native-device-info: "npm:14.0.4" languageName: unknown linkType: soft @@ -12128,15 +12128,15 @@ __metadata: fbjs: "npm:3.0.4" mendix: "npm:~10.0.9976" mime: "npm:3.0.0" + react-native-biometrics: "npm:3.0.1" react-native-blob-util: "npm:0.21.2" - react-native-device-info: "npm:13.0.0" + react-native-device-info: "npm:14.0.4" react-native-file-viewer: "npm:2.1.5" react-native-image-picker: "npm:7.2.3" react-native-localize: "npm:3.2.1" react-native-permissions: "npm:4.1.5" react-native-schedule-exact-alarm-permission: "npm:^0.1.3" react-native-sound: "npm:0.11.0" - react-native-touch-id: "npm:4.4.1" rimraf: "npm:^4.4.1" rollup: "npm:^2.79.2" url-parse: "npm:^1.4.7" @@ -14067,6 +14067,15 @@ __metadata: languageName: node linkType: hard +"react-native-biometrics@npm:3.0.1": + version: 3.0.1 + resolution: "react-native-biometrics@npm:3.0.1" + peerDependencies: + react-native: ">=0.60.0" + checksum: 10/abbbe0b4ba0470ae6b8acdc9f1914b8356349096c58abd3b195d832ae7f007b9876191d08dd88b27c1cc9b69a43f4cd3b320307cd7f066e4475da4dfd696e198 + languageName: node + linkType: hard + "react-native-blob-util@npm:0.21.2": version: 0.21.2 resolution: "react-native-blob-util@npm:0.21.2" @@ -14103,12 +14112,12 @@ __metadata: languageName: node linkType: hard -"react-native-device-info@npm:13.0.0": - version: 13.0.0 - resolution: "react-native-device-info@npm:13.0.0" +"react-native-device-info@npm:14.0.4": + version: 14.0.4 + resolution: "react-native-device-info@npm:14.0.4" peerDependencies: react-native: "*" - checksum: 10/56cf41aa1d533d81b182973939cc3663285c7a6a93e6465b88feedefc1a7809a5d937f3588e145a445a1e0a74eda8242a46e1e67b33753909ad71e3e1216aeb1 + checksum: 10/bf031048551597b1a9ab2965d498cbd073eacf50005dffa4e3496286578734a45854141d47654e7e58ef8531b8c2cd6d1670bfd75625271c91aab3b3b8d0a8d8 languageName: node linkType: hard @@ -14367,13 +14376,6 @@ __metadata: languageName: node linkType: hard -"react-native-touch-id@npm:4.4.1": - version: 4.4.1 - resolution: "react-native-touch-id@npm:4.4.1" - checksum: 10/68973f838a42077fb3b7a7b5f1855f92d9aab82474f566c8f22a6354c9257fb489a221b2e4ff82d549bc2f2caa5335fbd196b23bdf0b197fa2eb27f1c90f6302 - languageName: node - linkType: hard - "react-native-turbo-image@npm:1.22.3": version: 1.22.3 resolution: "react-native-turbo-image@npm:1.22.3" From e406366c884a77b50e8a842b8abaae27de6b3a06 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 10 Apr 2025 23:04:51 +0200 Subject: [PATCH 09/23] snapshot update --- .../backgroundGradient.spec.tsx.snap | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap b/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap index 3f6267ef5..16e103271 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap +++ b/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap @@ -42,7 +42,7 @@ exports[`Background gradient render background gradient with custom style 1`] = - - - - - Date: Fri, 11 Apr 2025 10:49:21 +0200 Subject: [PATCH 10/23] chore: return the result --- .../src/authentication/IsBiometricAuthenticationSupported.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts b/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts index 0fb5a7e07..99a1b8d48 100644 --- a/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts +++ b/packages/jsActions/mobile-resources-native/src/authentication/IsBiometricAuthenticationSupported.ts @@ -21,7 +21,7 @@ export async function IsBiometricAuthenticationSupported(): Promise { return rnBiometrics .isSensorAvailable() - .then(() => true) + .then(result => result.available) .catch(() => false); // END USER CODE From ce9505993e50167a94cad6bad862c7c22f19de3f Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Tue, 15 Apr 2025 14:46:11 +0200 Subject: [PATCH 11/23] revert back @d11/react-native-fast-image until fixing compiling issues --- packages/pluggableWidgets/image-native/CHANGELOG.md | 2 -- packages/pluggableWidgets/image-native/package.json | 4 ++-- .../image-native/src/components/ImageIconSVG.tsx | 8 ++++---- packages/pluggableWidgets/image-native/src/package.xml | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/pluggableWidgets/image-native/CHANGELOG.md b/packages/pluggableWidgets/image-native/CHANGELOG.md index 14831606c..30a9b2cd3 100644 --- a/packages/pluggableWidgets/image-native/CHANGELOG.md +++ b/packages/pluggableWidgets/image-native/CHANGELOG.md @@ -6,8 +6,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] -- Migrated react-native-fast-image to react-native-turbo-image to support react-native new architecture. - ## [3.0.0] - 2024-12-3 ### Changed diff --git a/packages/pluggableWidgets/image-native/package.json b/packages/pluggableWidgets/image-native/package.json index cad71b027..f3ebd6e22 100644 --- a/packages/pluggableWidgets/image-native/package.json +++ b/packages/pluggableWidgets/image-native/package.json @@ -1,7 +1,7 @@ { "name": "image-native", "widgetName": "Image", - "version": "3.1.0", + "version": "3.0.0", "description": "Display an image and enlarge it on click", "copyright": "© Mendix Technology BV 2022. All rights reserved.", "license": "Apache-2.0", @@ -30,8 +30,8 @@ "dependencies": { "@mendix/piw-native-utils-internal": "*", "@mendix/piw-utils-internal": "*", + "react-native-fast-image": "8.3.2", "react-native-svg": "15.7.1", - "react-native-turbo-image": "1.22.3", "react-native-vector-icons": "10.2.0" }, "devDependencies": { diff --git a/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx b/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx index 8914e6020..c1470bea6 100644 --- a/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx +++ b/packages/pluggableWidgets/image-native/src/components/ImageIconSVG.tsx @@ -1,12 +1,12 @@ import { createElement, FunctionComponent, Fragment, useCallback } from "react"; import { View } from "react-native"; import { SvgUri, SvgXml } from "react-native-svg"; +import FastImageComponent, { Source } from "react-native-fast-image"; import { extractStyles } from "@mendix/pluggable-widgets-tools"; import { CustomImageProps, GlyphIcon } from "../utils/imageUtils"; import { GlyphIcon as GlyphIconComponent } from "./fonts/font"; import { ResizeModeEnum } from "../../typings/ImageProps"; import { getPositionFromSVG } from "../utils/svgUtils"; -import TurboImage, { Source } from "react-native-turbo-image"; export interface DimensionsType { width?: number; @@ -65,9 +65,9 @@ export const ImageIconSVG: FunctionComponent = props => { if (image && (type === "staticImage" || type === "dynamicImage")) { return ( - - + From 2d1817942c32a491b4a417376db1c52da1579491 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Tue, 15 Apr 2025 14:47:08 +0200 Subject: [PATCH 12/23] implementation for react-native-track-player --- .../src/platform/PlaySound.ts | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts index e65193826..edde4097e 100644 --- a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts +++ b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 Sound from "react-native-sound"; +import TrackPlayer, { Event } from "react-native-track-player"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -34,19 +34,26 @@ export async function PlaySound(audioFile?: mendix.lib.MxObject): Promise const changedDate = audioFile.get("changedDate") as number; const url = mx.data.getDocumentUrl(guid, changedDate); - const audio = new Sound(url, undefined, error => { - if (error) { - return Promise.reject(new Error(error)); - } - - audio.play(success => { - audio.release(); - if (success) { - return Promise.resolve(); - } - return Promise.reject(new Error("Playback failed due to an audio encoding error")); + try { + await TrackPlayer.setupPlayer(); + + await TrackPlayer.reset(); + + await TrackPlayer.add({ + id: guid, + url, + title: "Audio Playback", + artist: "Unknown" }); - }); + await TrackPlayer.play(); + + const listener = TrackPlayer.addEventListener(Event.PlaybackQueueEnded, async () => { + listener.remove(); // cleanup + }); + } catch (error) { + console.error("Playback failed", error); + throw new Error("Playback failed due to an audio encoding error"); + } // END USER CODE } From 84cbb20a5520c7ab293af7c777fc96cb1376675d Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Tue, 15 Apr 2025 14:47:38 +0200 Subject: [PATCH 13/23] chore: empty string issue fixed on ios --- configs/e2e/native_dependencies.json | 2 +- .../mobile-resources-native/package.json | 2 +- .../CancelAllScheduledNotifications.ts | 7 +- .../CancelScheduledNotification.ts | 7 +- .../ClearAllDeliveredNotifications.ts | 7 +- .../src/notifications/DisplayNotification.ts | 4 +- .../src/notifications/ScheduleNotification.ts | 4 +- .../src/notifications/SetBadgeNumber.ts | 7 +- .../__snapshots__/Image.spec.tsx.snap | 176 +++++++++++------- yarn.lock | 42 +++-- 10 files changed, 151 insertions(+), 107 deletions(-) diff --git a/configs/e2e/native_dependencies.json b/configs/e2e/native_dependencies.json index c2b28fe46..5f50ddd19 100644 --- a/configs/e2e/native_dependencies.json +++ b/configs/e2e/native_dependencies.json @@ -4,7 +4,7 @@ "react-native-device-info": "14.0.4", "react-native-action-button": "2.8.5", "react-native-material-menu": "1.2.0", - "react-native-linear-gradient": "2.5.6", + "react-native-linear-gradient": "3.0.0-alpha.1", "@react-native-community/netinfo": "11.4.1", "react-native-svg": "15.11.1", "react-native-system-navigation-bar": "2.6.3", diff --git a/packages/jsActions/mobile-resources-native/package.json b/packages/jsActions/mobile-resources-native/package.json index dfe794f57..6a4f9be0d 100644 --- a/packages/jsActions/mobile-resources-native/package.json +++ b/packages/jsActions/mobile-resources-native/package.json @@ -40,7 +40,7 @@ "react-native-localize": "3.2.1", "react-native-permissions": "4.1.5", "react-native-schedule-exact-alarm-permission": "^0.1.3", - "react-native-sound": "0.11.0", + "react-native-track-player": "^4.1.1", "url-parse": "^1.4.7" }, "devDependencies": { diff --git a/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts b/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts index 092b821f4..e3e547625 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/CancelAllScheduledNotifications.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 { NativeModules, Platform } from "react-native"; +import { NativeModules } from "react-native"; import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE @@ -18,9 +18,8 @@ import notifee from "@notifee/react-native"; export async function CancelAllScheduledNotifications(): Promise { // BEGIN USER CODE // Documentation https://github.com/invertase/notifee - const isIOS = Platform.OS === "ios"; - if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { - return Promise.reject(new Error("Notifications module is not available in your app")); + if (NativeModules && !NativeModules.NotifeeApiModule) { + return Promise.reject(new Error("Notifee native module is not available in your app")); } notifee.cancelAllNotifications(); diff --git a/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts index ddcd5979c..d840fc9cd 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/CancelScheduledNotification.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 { NativeModules, Platform } from "react-native"; +import { NativeModules } from "react-native"; import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE @@ -18,9 +18,8 @@ import notifee from "@notifee/react-native"; export async function CancelScheduledNotification(notificationId?: string): Promise { // BEGIN USER CODE // Documentation Documentation https://github.com/invertase/notifee - const isIOS = Platform.OS === "ios"; - if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { - return Promise.reject(new Error("Notifications module is not available in your app")); + if (NativeModules && !NativeModules.NotifeeApiModule) { + return Promise.reject(new Error("Notifee native module is not available in your app")); } if (!notificationId) { diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts b/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts index 1249e9cad..cd0debaed 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ClearAllDeliveredNotifications.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 { NativeModules, Platform } from "react-native"; +import { NativeModules } from "react-native"; import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE @@ -18,9 +18,8 @@ import notifee from "@notifee/react-native"; export async function ClearAllDeliveredNotifications(): Promise { // BEGIN USER CODE // Documentation Documentation https://github.com/invertase/notifee - const isIOS = Platform.OS === "ios"; - if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { - return Promise.reject(new Error("Notifications module is not available in your app")); + if (NativeModules && !NativeModules.NotifeeApiModule) { + return Promise.reject(new Error("Notifee native module is not available in your app")); } notifee.cancelAllNotifications(); diff --git a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts index 8700ceb21..94e74179d 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts @@ -45,10 +45,10 @@ export async function DisplayNotification( android: { channelId, // smallIcon: "ic_notification", - sound: playSound ? "default" : undefined + ...(playSound ? { sound: "default" } : {}) }, ios: { - sound: playSound ? "default" : undefined + ...(playSound ? { sound: "default" } : {}) } }; diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts index 06511f340..80608e9b3 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts @@ -58,10 +58,10 @@ export async function ScheduleNotification( android: { channelId, smallIcon: "ic_notification", - sound: playSound ? "default" : undefined + ...(playSound ? { sound: "default" } : {}) }, ios: { - sound: !!playSound + ...(playSound ? { sound: "default" } : {}) } }; diff --git a/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts b/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts index f6b98cbfd..b59ad7989 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/SetBadgeNumber.ts @@ -6,7 +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 { Big } from "big.js"; -import { NativeModules, Platform } from "react-native"; +import { NativeModules } from "react-native"; import notifee from "@notifee/react-native"; // BEGIN EXTRA CODE @@ -20,9 +20,8 @@ export async function SetBadgeNumber(badgeNumber?: Big): Promise { // BEGIN USER CODE // Documentation Documentation https://github.com/invertase/notifee - const isIOS = Platform.OS === "ios"; - if (NativeModules && isIOS && !NativeModules.RNCPushNotificationIOS) { - return Promise.reject(new Error("Notifications module is not available in your app")); + if (NativeModules && !NativeModules.NotifeeApiModule) { + return Promise.reject(new Error("Notifee native module is not available in your app")); } if (!badgeNumber) { diff --git a/packages/pluggableWidgets/image-native/src/components/__tests__/__snapshots__/Image.spec.tsx.snap b/packages/pluggableWidgets/image-native/src/components/__tests__/__snapshots__/Image.spec.tsx.snap index f57ce9009..034282ebf 100644 --- a/packages/pluggableWidgets/image-native/src/components/__tests__/__snapshots__/Image.spec.tsx.snap +++ b/packages/pluggableWidgets/image-native/src/components/__tests__/__snapshots__/Image.spec.tsx.snap @@ -796,16 +796,15 @@ exports[`Widget Dynamic Image renders the structure 1`] = ` "minWidth": 8, }, ], - undefined, ] } > - - - - - - - - - - - - - - - - - - - - =0.60.0" + checksum: 10/398def3b64af545cca5380087637026e873216c3f009146cf7da8bdb44ab9aca38d17b38cbf268c50125a4b282f67a7ae861531b5ee03832962e71efdf11279b + languageName: node + linkType: hard + "react-native-file-viewer@npm:2.1.5": version: 2.1.5 resolution: "react-native-file-viewer@npm:2.1.5" @@ -14343,15 +14353,6 @@ __metadata: languageName: node linkType: hard -"react-native-sound@npm:0.11.0": - version: 0.11.0 - resolution: "react-native-sound@npm:0.11.0" - peerDependencies: - react-native: ">=0.8.0" - checksum: 10/17eff55af971ef6d76d678a8de5b556cffaeced38e7c64277d441e78a55773fd5b34e986c545b8d42059e22bb66070a5ccbacd237496d9f3c9fed7ec8f3776c3 - languageName: node - linkType: hard - "react-native-svg@npm:15.7.1": version: 15.7.1 resolution: "react-native-svg@npm:15.7.1" @@ -14376,13 +14377,20 @@ __metadata: languageName: node linkType: hard -"react-native-turbo-image@npm:1.22.3": - version: 1.22.3 - resolution: "react-native-turbo-image@npm:1.22.3" +"react-native-track-player@npm:^4.1.1": + version: 4.1.1 + resolution: "react-native-track-player@npm:4.1.1" peerDependencies: - react: "*" - react-native: "*" - checksum: 10/b09e4bbf95de81dee9c5929d87a216167f5d7bef0b9c0e898e2fe574f00b57437224eb32ea8380f75d9b4e5108ec2b6eac3830cde1ce9059feea66517e46c3e0 + react: ">=16.8.6" + react-native: ">=0.60.0-rc.2" + react-native-windows: ">=0.63.0" + shaka-player: ^4.7.9 + peerDependenciesMeta: + react-native-windows: + optional: true + shaka-player: + optional: true + checksum: 10/6e755319a3f86d279e23392a2dc36ee0a55280526b5796f36f5d80da044a9b1de9b38d77b48259d815723c512e5a0a6bc5d4fda6f54b73d26f91b476c4cad9d2 languageName: node linkType: hard From 8be228b52d26d32e2143ee6d0808da495e96e1b5 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Wed, 16 Apr 2025 10:04:37 +0200 Subject: [PATCH 14/23] type check --- .../src/notifications/DisplayNotification.ts | 11 ++++++++--- .../src/notifications/ScheduleNotification.ts | 14 ++++++++++---- .../src/BackgroundGradient.tsx | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts index 94e74179d..7d842d34d 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 { Platform } from "react-native"; +import { NativeModules, Platform } from "react-native"; import notifee, { AndroidChannel, AndroidImportance, Notification } from "@notifee/react-native"; // BEGIN EXTRA CODE @@ -36,6 +36,11 @@ export async function DisplayNotification( throw new Error("Input parameter 'Body' is required"); } + // Documentation Documentation https://github.com/invertase/notifee + if (NativeModules && !NativeModules.NotifeeApiModule) { + return Promise.reject(new Error("Notifee native module is not available in your app")); + } + const channelId = "mendix-local-notifications"; await createNotificationChannelIfNeeded(channelId); @@ -60,8 +65,8 @@ export async function DisplayNotification( // Add custom data (actionName and actionGuid) to the notification if (actionName || actionGuid) { notification.data = { - actionName: actionName || null, - guid: actionGuid || null + actionName: actionName ?? "", + guid: actionGuid ?? "" }; } diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts index 80608e9b3..9d607d4dc 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts @@ -6,7 +6,13 @@ // - 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 { Platform } from "react-native"; -import notifee, { TimestampTrigger, TriggerType, AndroidChannel, AndroidImportance } from "@notifee/react-native"; +import notifee, { + TimestampTrigger, + TriggerType, + AndroidChannel, + AndroidImportance, + Notification +} from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -51,7 +57,7 @@ export async function ScheduleNotification( timestamp: date.getTime() }; - const notification: any = { + const notification: Notification = { id: notificationId || undefined, title: title || undefined, body, @@ -71,8 +77,8 @@ export async function ScheduleNotification( if (actionName || actionGuid) { notification.data = { - actionName: actionName || null, - guid: actionGuid || null + actionName: actionName ?? "", + guid: actionGuid ?? "" }; } diff --git a/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx b/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx index 839af075d..eb509210c 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx +++ b/packages/pluggableWidgets/background-gradient-native/src/BackgroundGradient.tsx @@ -71,7 +71,7 @@ export function BackgroundGradient({ name, colorList, content, onClick, style }: opacity: onClick?.canExecute && pressed ? opacity * 0.3 : opacity })} > - + {content} From 0f3d34e962e3dcd28f2a151d4551ec180bb50393 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Wed, 16 Apr 2025 10:05:14 +0200 Subject: [PATCH 15/23] dont run setup player functionality for setup player in every run --- .../mobile-resources-native/src/platform/PlaySound.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts index edde4097e..a64527f07 100644 --- a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts +++ b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 TrackPlayer, { Event } from "react-native-track-player"; +import TrackPlayer, { Event, State } from "react-native-track-player"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -34,8 +34,15 @@ export async function PlaySound(audioFile?: mendix.lib.MxObject): Promise const changedDate = audioFile.get("changedDate") as number; const url = mx.data.getDocumentUrl(guid, changedDate); + const isPlayerInitialized = async () => { + const currentTrack = await TrackPlayer.getActiveTrack(); + return currentTrack !== null; + }; + try { - await TrackPlayer.setupPlayer(); + if (!isPlayerInitialized()) { + await TrackPlayer.setupPlayer(); + } await TrackPlayer.reset(); From 2dcf20c7c99a890284a58dbba4ab24d67fc98a97 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Fri, 18 Apr 2025 11:47:26 +0200 Subject: [PATCH 16/23] decreased version from alpha to latest stabil --- .../background-gradient-native/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/pluggableWidgets/background-gradient-native/package.json b/packages/pluggableWidgets/background-gradient-native/package.json index cc0f128b4..74e6c6ecb 100644 --- a/packages/pluggableWidgets/background-gradient-native/package.json +++ b/packages/pluggableWidgets/background-gradient-native/package.json @@ -30,6 +30,6 @@ }, "dependencies": { "@mendix/piw-utils-internal": "*", - "react-native-linear-gradient": "3.0.0-alpha.1" + "react-native-linear-gradient": "2.8.3" } } diff --git a/yarn.lock b/yarn.lock index 8130efd1e..7e9725d4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5137,7 +5137,7 @@ __metadata: "@mendix/piw-utils-internal": "npm:*" "@mendix/pluggable-widgets-tools": "npm:~10.0.1" eslint: "npm:^7.32.0" - react-native-linear-gradient: "npm:3.0.0-alpha.1" + react-native-linear-gradient: "npm:2.8.3" languageName: unknown linkType: soft @@ -14180,13 +14180,13 @@ __metadata: languageName: node linkType: hard -"react-native-linear-gradient@npm:3.0.0-alpha.1": - version: 3.0.0-alpha.1 - resolution: "react-native-linear-gradient@npm:3.0.0-alpha.1" +"react-native-linear-gradient@npm:2.8.3": + version: 2.8.3 + resolution: "react-native-linear-gradient@npm:2.8.3" peerDependencies: react: "*" react-native: "*" - checksum: 10/95eef8707bf8c38b16d265c46d945ee9c10a27a0da8b64bdf00ea62d905e303d30e06c61a065f85aa27bbfa3faa124c172e8f95335363fd6cb089f939f62ba85 + checksum: 10/db18c7ae4b68afe8b6f12c67defeeccda7a3cff4ee14a0b2d92ff2581d53bd2e65bf29837cf2828abb3d8d1f3cef3f808e8cc1c5d4c8da5dd6f1d09e2b9c2c55 languageName: node linkType: hard From 3f2a201d0033fa530ff531abadcf325a59dee11e Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 24 Apr 2025 01:23:14 +0200 Subject: [PATCH 17/23] chore: snapshot update --- configs/e2e/native_dependencies.json | 2 +- .../backgroundGradient.spec.tsx.snap | 90 +++++++++---------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/configs/e2e/native_dependencies.json b/configs/e2e/native_dependencies.json index 5f50ddd19..fd61c93fc 100644 --- a/configs/e2e/native_dependencies.json +++ b/configs/e2e/native_dependencies.json @@ -4,7 +4,7 @@ "react-native-device-info": "14.0.4", "react-native-action-button": "2.8.5", "react-native-material-menu": "1.2.0", - "react-native-linear-gradient": "3.0.0-alpha.1", + "react-native-linear-gradient": "2.8.3", "@react-native-community/netinfo": "11.4.1", "react-native-svg": "15.11.1", "react-native-system-navigation-bar": "2.6.3", diff --git a/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap b/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap index 16e103271..3f6267ef5 100644 --- a/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap +++ b/packages/pluggableWidgets/background-gradient-native/src/__tests__/__snapshots__/backgroundGradient.spec.tsx.snap @@ -42,7 +42,7 @@ exports[`Background gradient render background gradient with custom style 1`] = - - - - - Date: Fri, 2 May 2025 12:22:48 +0200 Subject: [PATCH 18/23] initialization issue was fixed for track player --- .../src/platform/PlaySound.ts | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts index a64527f07..c8b1fcd05 100644 --- a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts +++ b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 TrackPlayer, { Event, State } from "react-native-track-player"; +import TrackPlayer, { Event } from "react-native-track-player"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -34,16 +34,7 @@ export async function PlaySound(audioFile?: mendix.lib.MxObject): Promise const changedDate = audioFile.get("changedDate") as number; const url = mx.data.getDocumentUrl(guid, changedDate); - const isPlayerInitialized = async () => { - const currentTrack = await TrackPlayer.getActiveTrack(); - return currentTrack !== null; - }; - - try { - if (!isPlayerInitialized()) { - await TrackPlayer.setupPlayer(); - } - + const play = async () => { await TrackPlayer.reset(); await TrackPlayer.add({ @@ -58,9 +49,15 @@ export async function PlaySound(audioFile?: mendix.lib.MxObject): Promise const listener = TrackPlayer.addEventListener(Event.PlaybackQueueEnded, async () => { listener.remove(); // cleanup }); + }; + + try { + await play(); } catch (error) { + // it means the player wasn't initialized yet. + await TrackPlayer.setupPlayer(); + await play(); console.error("Playback failed", error); - throw new Error("Playback failed due to an audio encoding error"); } // END USER CODE } From e8703da973e500f2137df8747862b8a70b3665f5 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Tue, 6 May 2025 21:56:06 +0200 Subject: [PATCH 19/23] fixed sound and schedule notification --- .../src/notifications/DisplayNotification.ts | 32 ++++++++-------- .../src/notifications/ScheduleNotification.ts | 38 +++++++++---------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts index 7d842d34d..f20e1e2c1 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts @@ -48,12 +48,7 @@ export async function DisplayNotification( title: title || undefined, body, android: { - channelId, - // smallIcon: "ic_notification", - ...(playSound ? { sound: "default" } : {}) - }, - ios: { - ...(playSound ? { sound: "default" } : {}) + channelId } }; @@ -73,17 +68,20 @@ export async function DisplayNotification( await notifee.displayNotification(notification); async function createNotificationChannelIfNeeded(channelId: string): Promise { - if (Platform.OS === "android") { - const channels = await notifee.getChannels(); - const isChannelExist = channels.some(c => c.name === channelId); - if (!isChannelExist) { - const channel: AndroidChannel = { - id: channelId, - name: "Local Notifications", - importance: AndroidImportance.HIGH - }; - await notifee.createChannel(channel); - } + const existingChannel = await notifee.getChannel(channelId); + const sound = playSound ? "default" : undefined; + const channel: AndroidChannel = { + id: channelId, + name: "Local Notifications", + importance: AndroidImportance.HIGH, + ...(playSound ? { sound: "default" } : {}) + }; + if (existingChannel === null) { + await notifee.createChannel(channel); + } + if (existingChannel?.sound !== sound) { + await notifee.deleteChannel(channelId); + await notifee.createChannel(channel); } } diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts index 9d607d4dc..d37976a33 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts @@ -11,7 +11,8 @@ import notifee, { TriggerType, AndroidChannel, AndroidImportance, - Notification + Notification, + AlarmType } from "@notifee/react-native"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -54,7 +55,8 @@ export async function ScheduleNotification( const trigger: TimestampTrigger = { type: TriggerType.TIMESTAMP, - timestamp: date.getTime() + timestamp: date.getTime(), + alarmManager: { allowWhileIdle: true, type: AlarmType.SET_EXACT_AND_ALLOW_WHILE_IDLE } }; const notification: Notification = { @@ -62,12 +64,7 @@ export async function ScheduleNotification( title: title || undefined, body, android: { - channelId, - smallIcon: "ic_notification", - ...(playSound ? { sound: "default" } : {}) - }, - ios: { - ...(playSound ? { sound: "default" } : {}) + channelId } }; @@ -83,17 +80,20 @@ export async function ScheduleNotification( } async function createNotificationChannelIfNeeded(channelId: string): Promise { - if (Platform.OS === "android") { - const channels = await notifee.getChannels(); - const isChannelExist = channels.some(c => c.name === channelId); - if (!isChannelExist) { - const channel: AndroidChannel = { - id: channelId, - name: "Local Notifications", - importance: AndroidImportance.HIGH - }; - await notifee.createChannel(channel); - } + const existingChannel = await notifee.getChannel(channelId); + const sound = playSound ? "default" : undefined; + const channel: AndroidChannel = { + id: channelId, + name: "Local Notifications", + importance: AndroidImportance.HIGH, + ...(playSound ? { sound: "default" } : {}) + }; + if (existingChannel === null) { + await notifee.createChannel(channel); + } + if (existingChannel?.sound !== sound) { + await notifee.deleteChannel(channelId); + await notifee.createChannel(channel); } } From 3c68f86a227082805d570e2a4008372e60babcfb Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Wed, 7 May 2025 11:28:47 +0200 Subject: [PATCH 20/23] dont create a channel if platform is ios since it's not needed --- .../src/notifications/DisplayNotification.ts | 5 +++-- .../src/notifications/ScheduleNotification.ts | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts index f20e1e2c1..6fe1ecf91 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts @@ -52,12 +52,10 @@ export async function DisplayNotification( } }; - // Add subtitle for iOS (if provided) if (subtitle && Platform.OS === "ios") { notification.subtitle = subtitle; } - // Add custom data (actionName and actionGuid) to the notification if (actionName || actionGuid) { notification.data = { actionName: actionName ?? "", @@ -68,6 +66,9 @@ export async function DisplayNotification( await notifee.displayNotification(notification); async function createNotificationChannelIfNeeded(channelId: string): Promise { + if (Platform.OS === "ios") { + return; + } const existingChannel = await notifee.getChannel(channelId); const sound = playSound ? "default" : undefined; const channel: AndroidChannel = { diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts index d37976a33..a708799f3 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts @@ -80,6 +80,9 @@ export async function ScheduleNotification( } async function createNotificationChannelIfNeeded(channelId: string): Promise { + if (Platform.OS === "ios") { + return; + } const existingChannel = await notifee.getChannel(channelId); const sound = playSound ? "default" : undefined; const channel: AndroidChannel = { From 78f18cb921fffa4557d3164a0b5de3b8a99bc7d0 Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 15 May 2025 00:43:52 +0200 Subject: [PATCH 21/23] fixed sound issue --- .../src/notifications/DisplayNotification.ts | 12 +++--------- .../src/notifications/ScheduleNotification.ts | 7 +------ 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts index 6fe1ecf91..bbfff2e5f 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/DisplayNotification.ts @@ -41,15 +41,14 @@ export async function DisplayNotification( return Promise.reject(new Error("Notifee native module is not available in your app")); } - const channelId = "mendix-local-notifications"; + const channelId = playSound ? "mendix-local-notifications-withsound" : "mendix-local-notifications"; await createNotificationChannelIfNeeded(channelId); const notification: Notification = { title: title || undefined, body, - android: { - channelId - } + android: { channelId, sound: "default" }, + ios: playSound ? { sound: "default" } : {} }; if (subtitle && Platform.OS === "ios") { @@ -70,7 +69,6 @@ export async function DisplayNotification( return; } const existingChannel = await notifee.getChannel(channelId); - const sound = playSound ? "default" : undefined; const channel: AndroidChannel = { id: channelId, name: "Local Notifications", @@ -80,10 +78,6 @@ export async function DisplayNotification( if (existingChannel === null) { await notifee.createChannel(channel); } - if (existingChannel?.sound !== sound) { - await notifee.deleteChannel(channelId); - await notifee.createChannel(channel); - } } return Promise.resolve(); diff --git a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts index a708799f3..a0683e593 100644 --- a/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts +++ b/packages/jsActions/mobile-resources-native/src/notifications/ScheduleNotification.ts @@ -42,7 +42,7 @@ export async function ScheduleNotification( actionGuid?: string ): Promise { // BEGIN USER CODE - const channelId = "mendix-local-notifications"; + const channelId = playSound ? "mendix-local-notifications-withsound" : "mendix-local-notifications"; await createNotificationChannelIfNeeded(channelId); if (!body) { @@ -84,7 +84,6 @@ export async function ScheduleNotification( return; } const existingChannel = await notifee.getChannel(channelId); - const sound = playSound ? "default" : undefined; const channel: AndroidChannel = { id: channelId, name: "Local Notifications", @@ -94,10 +93,6 @@ export async function ScheduleNotification( if (existingChannel === null) { await notifee.createChannel(channel); } - if (existingChannel?.sound !== sound) { - await notifee.deleteChannel(channelId); - await notifee.createChannel(channel); - } } await notifee.createTriggerNotification(notification, trigger); From 058bac8af497be4383e853d607876b711296eb8d Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 15 May 2025 01:16:30 +0200 Subject: [PATCH 22/23] revert "react-native-track-player" --- .../mobile-resources-native/package.json | 2 +- .../src/platform/PlaySound.ts | 37 +++++++------------ yarn.lock | 28 +++++--------- 3 files changed, 24 insertions(+), 43 deletions(-) diff --git a/packages/jsActions/mobile-resources-native/package.json b/packages/jsActions/mobile-resources-native/package.json index 6a4f9be0d..dfe794f57 100644 --- a/packages/jsActions/mobile-resources-native/package.json +++ b/packages/jsActions/mobile-resources-native/package.json @@ -40,7 +40,7 @@ "react-native-localize": "3.2.1", "react-native-permissions": "4.1.5", "react-native-schedule-exact-alarm-permission": "^0.1.3", - "react-native-track-player": "^4.1.1", + "react-native-sound": "0.11.0", "url-parse": "^1.4.7" }, "devDependencies": { diff --git a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts index c8b1fcd05..e65193826 100644 --- a/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts +++ b/packages/jsActions/mobile-resources-native/src/platform/PlaySound.ts @@ -5,7 +5,7 @@ // - the code between BEGIN USER CODE and END USER CODE // - 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 TrackPlayer, { Event } from "react-native-track-player"; +import Sound from "react-native-sound"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -34,30 +34,19 @@ export async function PlaySound(audioFile?: mendix.lib.MxObject): Promise const changedDate = audioFile.get("changedDate") as number; const url = mx.data.getDocumentUrl(guid, changedDate); - const play = async () => { - await TrackPlayer.reset(); - - await TrackPlayer.add({ - id: guid, - url, - title: "Audio Playback", - artist: "Unknown" + const audio = new Sound(url, undefined, error => { + if (error) { + return Promise.reject(new Error(error)); + } + + audio.play(success => { + audio.release(); + if (success) { + return Promise.resolve(); + } + return Promise.reject(new Error("Playback failed due to an audio encoding error")); }); + }); - await TrackPlayer.play(); - - const listener = TrackPlayer.addEventListener(Event.PlaybackQueueEnded, async () => { - listener.remove(); // cleanup - }); - }; - - try { - await play(); - } catch (error) { - // it means the player wasn't initialized yet. - await TrackPlayer.setupPlayer(); - await play(); - console.error("Playback failed", error); - } // END USER CODE } diff --git a/yarn.lock b/yarn.lock index 7e9725d4f..367a72640 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12136,7 +12136,7 @@ __metadata: react-native-localize: "npm:3.2.1" react-native-permissions: "npm:4.1.5" react-native-schedule-exact-alarm-permission: "npm:^0.1.3" - react-native-track-player: "npm:^4.1.1" + react-native-sound: "npm:0.11.0" rimraf: "npm:^4.4.1" rollup: "npm:^2.79.2" url-parse: "npm:^1.4.7" @@ -14353,6 +14353,15 @@ __metadata: languageName: node linkType: hard +"react-native-sound@npm:0.11.0": + version: 0.11.0 + resolution: "react-native-sound@npm:0.11.0" + peerDependencies: + react-native: ">=0.8.0" + checksum: 10/17eff55af971ef6d76d678a8de5b556cffaeced38e7c64277d441e78a55773fd5b34e986c545b8d42059e22bb66070a5ccbacd237496d9f3c9fed7ec8f3776c3 + languageName: node + linkType: hard + "react-native-svg@npm:15.7.1": version: 15.7.1 resolution: "react-native-svg@npm:15.7.1" @@ -14377,23 +14386,6 @@ __metadata: languageName: node linkType: hard -"react-native-track-player@npm:^4.1.1": - version: 4.1.1 - resolution: "react-native-track-player@npm:4.1.1" - peerDependencies: - react: ">=16.8.6" - react-native: ">=0.60.0-rc.2" - react-native-windows: ">=0.63.0" - shaka-player: ^4.7.9 - peerDependenciesMeta: - react-native-windows: - optional: true - shaka-player: - optional: true - checksum: 10/6e755319a3f86d279e23392a2dc36ee0a55280526b5796f36f5d80da044a9b1de9b38d77b48259d815723c512e5a0a6bc5d4fda6f54b73d26f91b476c4cad9d2 - languageName: node - linkType: hard - "react-native-vector-icons@npm:10.2.0": version: 10.2.0 resolution: "react-native-vector-icons@npm:10.2.0" From f0dd481ab5955e8715cac2447051f8bc9dc4e25c Mon Sep 17 00:00:00 2001 From: "Harun.Karahan" Date: Thu, 5 Jun 2025 15:41:08 +0200 Subject: [PATCH 23/23] chore: changelog and versions --- packages/pluggableWidgets/intro-screen-native/CHANGELOG.md | 2 ++ packages/pluggableWidgets/intro-screen-native/package.json | 2 +- packages/pluggableWidgets/intro-screen-native/src/package.xml | 2 +- packages/pluggableWidgets/notifications-native/CHANGELOG.md | 2 ++ packages/pluggableWidgets/notifications-native/package.json | 2 +- packages/pluggableWidgets/notifications-native/src/package.xml | 2 +- 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md b/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md index 9dbb2a298..7dacc5273 100644 --- a/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md +++ b/packages/pluggableWidgets/intro-screen-native/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +- Updated react-native-device-info to latest version. + ### Fixed - We have fixed defaultProps deprecation warning. diff --git a/packages/pluggableWidgets/intro-screen-native/package.json b/packages/pluggableWidgets/intro-screen-native/package.json index 847673857..bf3feb715 100644 --- a/packages/pluggableWidgets/intro-screen-native/package.json +++ b/packages/pluggableWidgets/intro-screen-native/package.json @@ -1,7 +1,7 @@ { "name": "intro-screen-native", "widgetName": "IntroScreen", - "version": "4.0.1", + "version": "4.1.0", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/pluggableWidgets/intro-screen-native/src/package.xml b/packages/pluggableWidgets/intro-screen-native/src/package.xml index e6a128883..34d0ef2ea 100644 --- a/packages/pluggableWidgets/intro-screen-native/src/package.xml +++ b/packages/pluggableWidgets/intro-screen-native/src/package.xml @@ -1,6 +1,6 @@ - + diff --git a/packages/pluggableWidgets/notifications-native/CHANGELOG.md b/packages/pluggableWidgets/notifications-native/CHANGELOG.md index eedb8ae3c..4d6cee63d 100644 --- a/packages/pluggableWidgets/notifications-native/CHANGELOG.md +++ b/packages/pluggableWidgets/notifications-native/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +- The widget has been migrated to notifee. + ## [4.1.0] - 2024-12-3 ### Changed diff --git a/packages/pluggableWidgets/notifications-native/package.json b/packages/pluggableWidgets/notifications-native/package.json index 10f6732e4..4c4807592 100644 --- a/packages/pluggableWidgets/notifications-native/package.json +++ b/packages/pluggableWidgets/notifications-native/package.json @@ -1,7 +1,7 @@ { "name": "notifications-native", "widgetName": "Notifications", - "version": "4.1.0", + "version": "5.0.0", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/pluggableWidgets/notifications-native/src/package.xml b/packages/pluggableWidgets/notifications-native/src/package.xml index 01942a958..f9b7fcb99 100644 --- a/packages/pluggableWidgets/notifications-native/src/package.xml +++ b/packages/pluggableWidgets/notifications-native/src/package.xml @@ -1,6 +1,6 @@ - +