diff --git a/configs/e2e/native_dependencies.json b/configs/e2e/native_dependencies.json index 557d6f104..26e365e04 100644 --- a/configs/e2e/native_dependencies.json +++ b/configs/e2e/native_dependencies.json @@ -16,6 +16,6 @@ "react-native-file-viewer-turbo": "0.6.0", "react-native-localize": "3.2.1", "react-native-image-picker": "7.2.3", - "react-native-permissions": "4.1.5", + "react-native-permissions": "5.4.2", "react-native-webview": "13.13.2" } diff --git a/configs/jsactions/rollup-plugin-collect-dependencies.mjs b/configs/jsactions/rollup-plugin-collect-dependencies.mjs index 347fdb552..1a6d4920d 100644 --- a/configs/jsactions/rollup-plugin-collect-dependencies.mjs +++ b/configs/jsactions/rollup-plugin-collect-dependencies.mjs @@ -2,9 +2,8 @@ import fg from "fast-glob"; import fsExtra from "fs-extra"; -import { existsSync, readFileSync, writeFileSync } from "fs"; +import { existsSync, readFileSync, writeFileSync, cpSync, lstatSync, realpathSync } from "fs"; import { dirname, join, parse } from "path"; -import copy from "recursive-copy"; import { promisify } from "util"; import resolve from "resolve"; import _ from "lodash"; @@ -172,15 +171,36 @@ export async function copyJsModule(moduleSourcePath, to) { if (existsSync(to)) { return; } - return promisify(copy)(moduleSourcePath, to, { - filter: [ - "**/*.*", - LICENSE_GLOB, - "!**/{android,ios,windows,mac,jest,github,gradle,__*__,docs,jest,example*}/**/*", - "!**/*.{config,setup}.*", - "!**/*.{podspec,flow}" - ], - overwrite: true + + // Check if the source is a symlink and resolve it to the actual path + let actualSourcePath = moduleSourcePath; + if (lstatSync(moduleSourcePath).isSymbolicLink()) { + actualSourcePath = realpathSync(moduleSourcePath); + } + + cpSync(actualSourcePath, to, { + recursive: true, + dereference: true, // Follow symlinks and copy the actual files + filter: (src, dest) => { + const relativePath = src.replace(actualSourcePath, "").replace(/^[\\/]/, ""); + + // Skip certain directories + if (relativePath.match(/[\\/](android|ios|windows|mac|jest|github|gradle|__.*__|docs|example.*)[\\/]/)) { + return false; + } + + // Skip certain file types + if (relativePath.match(/\.(config|setup)\.|\.podspec$|\.flow$/)) { + return false; + } + + // Include LICENSE files + if (relativePath.match(/license/i)) { + return true; + } + + return true; + } }); } diff --git a/configs/jsactions/rollup.config.mjs b/configs/jsactions/rollup.config.mjs index 4462d8acf..a36a0d134 100644 --- a/configs/jsactions/rollup.config.mjs +++ b/configs/jsactions/rollup.config.mjs @@ -93,17 +93,6 @@ export default async args => { } ); - // We dynamically import react-native-schedule-exact-alarm-permission as it works only on Android - // so we need to copy it here as collectDependencies won't detect it. - await copyJsModule( - // require returns a path to commonjs index.js file - join( - dirname(require.resolve("react-native-schedule-exact-alarm-permission")), - "../", - "../" - ), - join(outDir, "node_modules", "react-native-schedule-exact-alarm-permission") - ); } else if (args.configProject === "nanoflowcommons") { // `invariant` is being used silently by @react-native-community/geolocation; it is not listed as a dependency nor peerDependency. // https://github.dev/react-native-geolocation/react-native-geolocation/blob/1786929f2be581da91082ff857c2393da5e597b3/js/implementation.native.js#L13 diff --git a/packages/jsActions/mobile-resources-native/CHANGELOG.md b/packages/jsActions/mobile-resources-native/CHANGELOG.md index d9b260611..c9793d90e 100644 --- a/packages/jsActions/mobile-resources-native/CHANGELOG.md +++ b/packages/jsActions/mobile-resources-native/CHANGELOG.md @@ -6,10 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] + +- We updated react-native-permissions to 5.4.2. + +- We removed react-native-schedule-exact-alarm-permission since it's no longer required. + - Updated react-native from version 0.75.4 to 0.77.3. - We migrated from react-native-file-viewer to react-native-file-viewer-turbo for new architecture compatibility - File viewer now uses modal to display content + ## [10.0.0] Native Mobile Resources - 2025-3-31 - We migrated from react-native-inappbrowser-reborn to @swan-io/react-native-browser to prevent issues for next rn upgrade. diff --git a/packages/jsActions/mobile-resources-native/package.json b/packages/jsActions/mobile-resources-native/package.json index ac3eef3fb..a3c7b4e48 100644 --- a/packages/jsActions/mobile-resources-native/package.json +++ b/packages/jsActions/mobile-resources-native/package.json @@ -38,8 +38,7 @@ "react-native-file-viewer-turbo": "0.6.0", "react-native-image-picker": "7.2.3", "react-native-localize": "3.2.1", - "react-native-permissions": "4.1.5", - "react-native-schedule-exact-alarm-permission": "^0.1.3", + "react-native-permissions": "5.4.2", "react-native-sound": "0.11.0", "url-parse": "^1.4.7" }, diff --git a/packages/jsActions/mobile-resources-native/src/permissions/RequestGenericPermission.ts b/packages/jsActions/mobile-resources-native/src/permissions/RequestGenericPermission.ts index 9d72a4985..e6fb1f165 100644 --- a/packages/jsActions/mobile-resources-native/src/permissions/RequestGenericPermission.ts +++ b/packages/jsActions/mobile-resources-native/src/permissions/RequestGenericPermission.ts @@ -12,7 +12,8 @@ import { RESULTS, openSettings, Permission, - PERMISSIONS as RNPermissions + PERMISSIONS as RNPermissions, + canScheduleExactAlarms } from "react-native-permissions"; import { ANDROIDPermissionName, IOSPermissionName } from "../../typings/RequestGenericPermission"; @@ -30,18 +31,26 @@ function handleBlockedPermission(permission: string): void { const permissionName = permission.replace(/_IOS|_ANDROID/, ""); if (permissionName === "SCHEDULE_EXACT_ALARM") { - const RNExactAlarmPermission = require("react-native-schedule-exact-alarm-permission"); - - Alert.alert("", "Please allow setting alarms and reminders", [ - { text: "Go to alarm settings", onPress: () => RNExactAlarmPermission.getPermission(), isPreferred: true }, - { text: "Cancel", style: "cancel" } - ]); - } else { - Alert.alert("", `Please allow ${permissionName} access`, [ - { text: "Go to settings", onPress: () => openSettings(), isPreferred: true }, + return Alert.alert("", "Please allow setting alarms and reminders", [ + { + text: "Go to alarm settings", + onPress: async () => { + const canSchedule = await canScheduleExactAlarms(); + if (!canSchedule) { + // Check if permission is already granted + return openSettings("alarms"); + } + return openSettings(); + }, + isPreferred: true + }, { text: "Cancel", style: "cancel" } ]); } + return Alert.alert("", `Please allow ${permissionName} access`, [ + { text: "Go to settings", onPress: () => openSettings(), isPreferred: true }, + { text: "Cancel", style: "cancel" } + ]); } function mapPermissionName(permissionName: string): Permission | "android.permission.SCHEDULE_EXACT_ALARM" | undefined { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dad196fd0..eac0e7eae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -157,11 +157,8 @@ importers: specifier: 3.2.1 version: 3.2.1(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0) react-native-permissions: - specifier: 4.1.5 - version: 4.1.5(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0) - react-native-schedule-exact-alarm-permission: - specifier: ^0.1.3 - version: 0.1.5(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0) + specifier: 5.4.2 + version: 5.4.2(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0) react-native-sound: specifier: 0.11.0 version: 0.11.0(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0)) @@ -6509,8 +6506,8 @@ packages: react: 18.2.0 react-native: 0.77.3 - react-native-permissions@4.1.5: - resolution: {integrity: sha512-r6VMRacASmtRHS+GZ+5HQCp9p9kiE+UU9magHOZCXZLTJitdTuVHWZRrb4v4oqZGU+zAp3mZhTQftuMMv+WLUg==} + react-native-permissions@5.4.2: + resolution: {integrity: sha512-XNMoG1fxrB9q73MLn/ZfTaP7pS8qPu0KWypbeFKVTvoR+JJ3O7uedMOTH/mts9bTG+GKhShOoZ+k0CR63q9jwA==} peerDependencies: react: 18.2.0 react-native: 0.77.3 @@ -6544,12 +6541,6 @@ packages: react: 18.2.0 react-native: 0.77.3 - react-native-schedule-exact-alarm-permission@0.1.5: - resolution: {integrity: sha512-vm+vdaK9/ehY9i0k8gTxONunvtHRs31K9W5uz8yVJQEEXtxXSi1YjMZJS+YGKPhr8vrW/uxRlaGKpgu/F6lGEA==} - peerDependencies: - react: 18.2.0 - react-native: 0.77.3 - react-native-screens@4.13.1: resolution: {integrity: sha512-EESsMAtyzYcL3gpAI2NKKiIo+Ew0fnX4P4b3Zy/+MTc6SJIo3foJbZwdIWd/SUBswOf7IYCvWBppg+D8tbwnsw==} peerDependencies: @@ -15022,7 +15013,7 @@ snapshots: react-native: 0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0) react-native-animatable: 1.3.3 - react-native-permissions@4.1.5(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0): + react-native-permissions@5.4.2(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0): dependencies: react: 18.2.0 react-native: 0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0) @@ -15064,11 +15055,6 @@ snapshots: react: 18.2.0 react-native: 0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0) - react-native-schedule-exact-alarm-permission@0.1.5(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0): - dependencies: - react: 18.2.0 - react-native: 0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0) - react-native-screens@4.13.1(react-native@0.77.3(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@react-native-community/cli@14.1.0(typescript@5.8.3))(@types/react@18.3.23)(react@18.2.0))(react@18.2.0): dependencies: react: 18.2.0