From 24ef32a8d328aa141d7b0afcdc5ee7775a0690ee Mon Sep 17 00:00:00 2001 From: huhuanming Date: Mon, 12 Jan 2026 02:15:20 +0800 Subject: [PATCH 01/12] Update ReactNativeDeviceUtils.kt --- .../nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt index 8d0db39..e37a601 100644 --- a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt +++ b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt @@ -229,7 +229,8 @@ class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEven } fun callSpanningChangedListeners(isSpanning: Boolean) { - for (listener in spanningChangedListeners) { + // Create a snapshot to avoid ConcurrentModificationException when listeners modify the list during callbacks + for (listener in spanningChangedListeners.toList()) { listener.callback(isSpanning) } } From d107e99834c7c29c0d5cdfa1fe7ed961b7e12687 Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 01:28:00 +0800 Subject: [PATCH 02/12] feat: add manufacturer-specific foldable device detection with caching Add comprehensive foldable device detection for Xiaomi, Huawei, Vivo, OPPO, Samsung, Google, Motorola, and ZTE/Nubia devices using model lists and manufacturer-specific APIs. Cache detection results in PreferenceManager with key "1k_fold" to avoid repeated detection. Co-Authored-By: Claude Opus 4.5 --- .../ReactNativeDeviceUtils.kt | 339 +++++++++++++++++- 1 file changed, 321 insertions(+), 18 deletions(-) diff --git a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt index e37a601..11d8004 100644 --- a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt +++ b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt @@ -1,9 +1,12 @@ package com.margelo.nitro.reactnativedeviceutils import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager import android.graphics.Color import android.graphics.Rect import android.os.Build +import android.preference.PreferenceManager import androidx.core.content.ContextCompat import androidx.core.util.Consumer import androidx.window.layout.FoldingFeature @@ -25,7 +28,107 @@ data class Listener( @DoNotStrip class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEventListener { - + + companion object { + private const val PREF_KEY_FOLDABLE = "1k_fold" + + // Xiaomi foldable models + private val XIAOMI_FOLDABLE_MODELS = setOf( + "M2011J18C", // Mi MIX FOLD + "22061218C", // MIX FOLD 2 + "2308CPXD0C", // MIX FOLD 3 + "24072PX77C", // MIX FOLD 4 + "2405CPX3DC", // MIX FLIP + "2405CPX3DG" // MIX FLIP + ) + + // Huawei foldable models + private val HUAWEI_FOLDABLE_MODELS = setOf( + "TAH-AN00", "TAH-AN00m", "TAH-N29m", // Mate X + "GRL-AL10", // Mate X3 + "TET-AN50", // Mate Xs + "PAL-AL00", "PAL-LX9", // Mate Xs 2 + "ICL-AL20", "ICL-AL10", // Pocket S + "BAL-AL00", "BAL-L49", "BAL-AL60", // Pocket 2 + "PSD-AL00", // Mate X5 + "LEM-AL00", // Mate X6 + "ALT-AL10", "ALT-AL00", "ALT-L29", // Pocket + "TGW-AL00", "TGW-L29", // Mate X5 + "TWH-AL10", // Mate X3 + "DHF-AL00", "DHF-LX9", // Mate Xs 3 + "RHA-AN00m" // Magic V series + ) + + // Huawei foldable device codes + private val HUAWEI_FOLDABLE_DEVICES = setOf( + "HWTAH", "HWMRX", "HWTET", "HWPAL", "MateX" + ) + + // Vivo foldable models + private val VIVO_FOLDABLE_MODELS = setOf( + "V2337A", // X Fold3 + "V2330", // X Fold3 Pro + "V2178A", // X Fold + "V2229A", // X Fold+ + "V2266A", // X Flip + "V2303A", // X Fold2 + "V2256A" // X Fold S + ) + + // OPPO foldable models + private val OPPO_FOLDABLE_MODELS = setOf( + "PKH110", "CPH2671", // Find N3 + "PKH120", // Find N3 Flip + "CPH2499", // Find N2 + "PHN110", "PEUM00", // Find N2 Flip + "CPH2519", // Find N + "PHT110", "PGT110", // Find N3 series + "CPH2437" // Find N Flip + ) + + // Samsung foldable models (Japan carrier models) + private val SAMSUNG_FOLDABLE_MODELS = setOf( + // Galaxy Z Fold series (Japan) + "SCV47", "SCG04", "SC-54B", // Z Fold2 + "SCG12", "SC-54C", // Z Fold3 + "SCG17", "SC-54D", // Z Fold4 + "SCG23", "SC-54E", // Z Fold5 + "SCG29", // Z Fold6 + // Galaxy Z Flip series (Japan) + "SC-55B", "SCG11", // Z Flip3 + "SC-55C", "SCG16", // Z Flip4 + "SC-55D", "SCG22", // Z Flip5 + "SC-55E", "SCG28" // Z Flip6 + ) + + // Samsung foldable model prefixes + private val SAMSUNG_FOLDABLE_PREFIXES = listOf( + "SM-F9", // Galaxy Z Fold series + "SM-F7" // Galaxy Z Flip series + ) + + // Google foldable models + private val GOOGLE_FOLDABLE_MODELS = setOf( + "Pixel Fold", + "Pixel 9 Pro Fold" + ) + + // Motorola foldable models + private val MOTOROLA_FOLDABLE_MODELS = setOf( + "XT2323-3", // razr 40 Ultra + "XT2321-2", // razr 40 + "XT2451-4", // razr+ 2024 + "XT2251-1", // razr 2022 + "XT2451-3" // razr 2024 + ) + + // ZTE/Nubia foldable models + private val ZTE_FOLDABLE_MODELS = setOf( + "NX732J", // nubia Flip 5G + "NX724J" // nubia Flip + ) + } + private var windowLayoutInfo: WindowLayoutInfo? = null private var isSpanning = false private var layoutInfoConsumer: Consumer? = null @@ -53,37 +156,237 @@ class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEven // MARK: - Dual Screen Detection override fun isDualScreenDevice(): Boolean { + // Check cached value from PreferenceManager first + val cached = getCachedFoldableStatus() + if (cached == true) { + isDualScreenDeviceDetected = true + return true + } + if (isDualScreenDeviceDetected != null) { return isDualScreenDeviceDetected!! } + val activity = getCurrentActivity() ?: return false if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - isDualScreenDeviceDetected = hasFoldingFeature(activity) + val hasFolding = hasFoldingFeature(activity) + if (hasFolding) { + saveFoldableStatus(true) + } + isDualScreenDeviceDetected = hasFolding return isDualScreenDeviceDetected!! } isDualScreenDeviceDetected = false return isDualScreenDeviceDetected!! } - private fun isFoldableDeviceByName(): Boolean { - val deviceModel = Build.MODEL.lowercase() - val deviceManufacturer = Build.MANUFACTURER.lowercase() - - // Common foldable device patterns - val foldablePatterns = listOf( - "fold", "flip", "duo", "surface duo", "galaxy z", - "mate x", "mix fold", "find n", "magic v", - "pixel fold", "honor magic v", "vivo x fold", - "xiaomi mix fold", "oppo find n" - ) - - for (pattern in foldablePatterns) { - if (deviceModel.contains(pattern) || - (deviceManufacturer + " " + deviceModel).contains(pattern)) { - return true + // MARK: - Manufacturer-specific Foldable Detection + + /** + * Check if the device is a Xiaomi foldable + * Detection: Model list matching + system property check + */ + private fun isXiaomiFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "XIAOMI") return false + + val model = Build.MODEL.uppercase() + if (XIAOMI_FOLDABLE_MODELS.contains(model)) return true + + // Fallback: Check system property for foldable type + try { + val clazz = Class.forName("android.os.SystemProperties") + val method = clazz.getMethod("get", String::class.java) + val value = method.invoke(null, "persist.sys.muiltdisplay_type") as? String + if (value == "2") return true + } catch (e: Exception) { + // Ignore reflection errors + } + return false + } + + /** + * Check if the device is a Huawei foldable + * Detection: Model list + device code + system feature check + */ + private fun isHuaweiFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "HUAWEI") return false + + val model = Build.MODEL.uppercase() + val device = Build.DEVICE.uppercase() + + // Check model list + if (HUAWEI_FOLDABLE_MODELS.any { model.contains(it.uppercase()) }) return true + + // Check device codes + if (HUAWEI_FOLDABLE_DEVICES.any { device.contains(it.uppercase()) }) return true + + // Fallback: Check system feature for posture sensor + try { + val context = NitroModules.applicationContext + if (context != null) { + val pm = context.packageManager + if (pm.hasSystemFeature("com.huawei.hardware.sensor.posture")) { + return true + } } + } catch (e: Exception) { + // Ignore } return false } + + /** + * Check if the device is a Vivo foldable + * Detection: Model list + private API check + */ + private fun isVivoFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "VIVO") return false + + val model = Build.MODEL.uppercase() + if (VIVO_FOLDABLE_MODELS.contains(model)) return true + + // Fallback: Check using FtDeviceInfo API + try { + val clazz = Class.forName("android.util.FtDeviceInfo") + val method = clazz.getMethod("getDeviceType") + val deviceType = method.invoke(null) as? String + if (deviceType?.lowercase() == "foldable") return true + } catch (e: Exception) { + // Ignore reflection errors + } + return false + } + + /** + * Check if the device is an OPPO foldable + * Detection: Model list + feature config check + */ + private fun isOppoFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "OPPO") return false + + val model = Build.MODEL.uppercase() + if (OPPO_FOLDABLE_MODELS.contains(model)) return true + + // Fallback: Check using OplusFeatureConfigManager + try { + val clazz = Class.forName("com.oplus.content.OplusFeatureConfigManager") + val getInstanceMethod = clazz.getMethod("getInstance") + val instance = getInstanceMethod.invoke(null) + val hasFeatureMethod = clazz.getMethod("hasFeature", String::class.java) + val hasFeature = hasFeatureMethod.invoke(instance, "oplus.hardware.type.fold") as? Boolean + if (hasFeature == true) return true + } catch (e: Exception) { + // Ignore reflection errors + } + return false + } + + /** + * Check if the device is a Samsung foldable + * Detection: Model prefix matching + model list + */ + private fun isSamsungFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "SAMSUNG") return false + + val model = Build.MODEL.uppercase() + + // Check model prefixes (SM-F9xxx for Fold, SM-F7xxx for Flip) + for (prefix in SAMSUNG_FOLDABLE_PREFIXES) { + if (model.startsWith(prefix.uppercase())) return true + } + + // Check Japan carrier model list + if (SAMSUNG_FOLDABLE_MODELS.contains(model)) return true + + return false + } + + /** + * Check if the device is a Google foldable + */ + private fun isGoogleFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "GOOGLE") return false + + val model = Build.MODEL.uppercase() + return GOOGLE_FOLDABLE_MODELS.any { model.contains(it.uppercase()) } + } + + /** + * Check if the device is a Motorola foldable + */ + private fun isMotorolaFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "MOTOROLA") return false + + val model = Build.MODEL.uppercase() + return MOTOROLA_FOLDABLE_MODELS.contains(model) + } + + /** + * Check if the device is a ZTE/Nubia foldable + */ + private fun isZteFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "ZTE" && manufacturer != "NUBIA") return false + + val model = Build.MODEL.uppercase() + return ZTE_FOLDABLE_MODELS.contains(model) + } + + /** + * Get cached foldable status from PreferenceManager + */ + private fun getCachedFoldableStatus(): Boolean? { + try { + val context = NitroModules.applicationContext ?: return null + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + if (!prefs.contains(PREF_KEY_FOLDABLE)) return null + return prefs.getBoolean(PREF_KEY_FOLDABLE, false) + } catch (e: Exception) { + return null + } + } + + /** + * Save foldable status to PreferenceManager + */ + private fun saveFoldableStatus(isFoldable: Boolean) { + try { + val context = NitroModules.applicationContext ?: return + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + prefs.edit().putBoolean(PREF_KEY_FOLDABLE, isFoldable).apply() + } catch (e: Exception) { + // Ignore save errors + } + } + + /** + * Detect if device is foldable by checking manufacturer-specific methods + * Results are cached in PreferenceManager with key "1k_fold" + */ + private fun isFoldableDeviceByName(): Boolean { + // Check cached value first + val cached = getCachedFoldableStatus() + if (cached != null) return cached + + // Check each manufacturer + val isFoldable = isXiaomiFoldable() || + isHuaweiFoldable() || + isVivoFoldable() || + isOppoFoldable() || + isSamsungFoldable() || + isGoogleFoldable() || + isMotorolaFoldable() || + isZteFoldable() + + // Cache the result + return isFoldable + } private fun hasFoldingFeature(activity: Activity): Boolean { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { From 549bee07f23c8872c5ab4dd42a42a36dd83c59d0 Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 01:28:40 +0800 Subject: [PATCH 03/12] Update ReactNativeDeviceUtils.kt --- .../nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt index 11d8004..5619655 100644 --- a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt +++ b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt @@ -370,10 +370,6 @@ class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEven * Results are cached in PreferenceManager with key "1k_fold" */ private fun isFoldableDeviceByName(): Boolean { - // Check cached value first - val cached = getCachedFoldableStatus() - if (cached != null) return cached - // Check each manufacturer val isFoldable = isXiaomiFoldable() || isHuaweiFoldable() || From 6a59fff838823db1296b08bf063b32379c855338 Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 01:49:38 +0800 Subject: [PATCH 04/12] feat: expand foldable device list from Google Play supported devices Add comprehensive foldable device models extracted from the Google Play supported_devices.csv, including: - Vivo X Fold5 (V2436A, V2429) - ZTE Libero Flip, nubia Flip 2 5G - Honor Magic V2/V3/V5/Vs series - Vertu METAFLIP - Tecno PHANTOM V Fold/Flip series - Infinix ZERO Flip - Royole VERTU Ayxta Fold 3 - Complete Samsung Galaxy Z Fold/Flip model numbers Co-Authored-By: Claude Opus 4.5 --- .../ReactNativeDeviceUtils.kt | 210 +++++++++++++++--- 1 file changed, 177 insertions(+), 33 deletions(-) diff --git a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt index 5619655..434e0c9 100644 --- a/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt +++ b/native-modules/react-native-device-utils/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt @@ -29,6 +29,10 @@ data class Listener( @DoNotStrip class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEventListener { + /** + * Foldable device model constants for various manufacturers. + * Reference: https://storage.googleapis.com/play_public/supported_devices.html + */ companion object { private const val PREF_KEY_FOLDABLE = "1k_fold" @@ -66,66 +70,146 @@ class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEven // Vivo foldable models private val VIVO_FOLDABLE_MODELS = setOf( - "V2337A", // X Fold3 + "V2337A", // X Fold3 Pro "V2330", // X Fold3 Pro "V2178A", // X Fold "V2229A", // X Fold+ - "V2266A", // X Flip - "V2303A", // X Fold2 - "V2256A" // X Fold S + "V2266A", // vivo X Fold2 + "V2303A", // vivo X Fold3 + "V2256A", // X Flip + "V2436A", // X Fold5 + "V2429" // X Fold5 ) // OPPO foldable models private val OPPO_FOLDABLE_MODELS = setOf( - "PKH110", "CPH2671", // Find N3 - "PKH120", // Find N3 Flip - "CPH2499", // Find N2 - "PHN110", "PEUM00", // Find N2 Flip - "CPH2519", // Find N - "PHT110", "PGT110", // Find N3 series - "CPH2437" // Find N Flip + // Find N5 + "PKH110", "CPH2671", + // Find N5 卫星通信版 + "PKH120", + // Find N3 + "PHN110", "CPH2499", + // Find N3 Flip + "PHT110", "CPH2519", + // Find N2 Flip + "CPH2437", "PGT110", + // Find N + "PEUM00" ) - // Samsung foldable models (Japan carrier models) + // Samsung foldable models private val SAMSUNG_FOLDABLE_MODELS = setOf( - // Galaxy Z Fold series (Japan) - "SCV47", "SCG04", "SC-54B", // Z Fold2 - "SCG12", "SC-54C", // Z Fold3 - "SCG17", "SC-54D", // Z Fold4 - "SCG23", "SC-54E", // Z Fold5 - "SCG29", // Z Fold6 - // Galaxy Z Flip series (Japan) - "SC-55B", "SCG11", // Z Flip3 - "SC-55C", "SCG16", // Z Flip4 - "SC-55D", "SCG22", // Z Flip5 - "SC-55E", "SCG28" // Z Flip6 + // Galaxy Fold + "SCV44", "SM-F9000", "SM-F900F", "SM-F900U", "SM-F900U1", "SM-F900W", + // Galaxy Fold 5G + "SM-F907B", "SM-F907N", + // Galaxy Z Fold2 5G + "SM-F9160", "SM-F916B", "SM-F916N", "SM-F916Q", "SM-F916U", "SM-F916U1", "SM-F916W", + // Galaxy Z Fold3 5G + "SC-55B", "SCG11", "SM-F9260", "SM-F926B", "SM-F926N", "SM-F926U", "SM-F926U1", "SM-F926W", + // Galaxy Z Fold4 + "SC-55C", "SCG16", "SM-F9360", "SM-F936B", "SM-F936N", "SM-F936U", "SM-F936U1", "SM-F936W", + // Galaxy Z Fold5 + "SC-55D", "SCG22", "SM-F9460", "SM-F946B", "SM-F946N", "SM-F946Q", "SM-F946U", "SM-F946U1", "SM-F946W", + // Galaxy Z Fold6 + "SC-55E", "SCG28", "SM-F9560", "SM-F956B", "SM-F956N", "SM-F956Q", "SM-F956U", "SM-F956U1", "SM-F956W", + // Galaxy Z Fold7 + "SC-56F", "SCG34", "SM-F9660", "SM-F966B", "SM-F966N", "SM-F966Q", "SM-F966U", "SM-F966U1", "SM-F966W", "SM-F966Z", + // Galaxy Z Fold Special Edition + "SM-F958N", + // Galaxy Z TriFold + "SM-F9680", "SM-F968B", "SM-F968N", "SM-F968U1", + // Galaxy Z Flip + "SCV47", "SM-F7000", "SM-F700F", "SM-F700N", "SM-F700U", "SM-F700U1", "SM-F700W", + // Galaxy Z Flip 5G + "SCG04", "SM-F7070", "SM-F707B", "SM-F707N", "SM-F707U", "SM-F707U1", "SM-F707W", + // Galaxy Z Flip3 5G + "SC-54B", "SCG12", "SM-F7110", "SM-F711B", "SM-F711N", "SM-F711U", "SM-F711U1", "SM-F711W", + // Galaxy Z Flip4 + "SC-54C", "SCG17", "SM-F7210", "SM-F721B", "SM-F721C", "SM-F721N", "SM-F721U", "SM-F721U1", "SM-F721W", + // Galaxy Z Flip5 + "SC-54D", "SCG23", "SM-F7310", "SM-F731B", "SM-F731N", "SM-F731Q", "SM-F731U", "SM-F731U1", "SM-F731W", + // Galaxy Z Flip6 + "SC-54E", "SCG29", "SM-F7410", "SM-F741B", "SM-F741N", "SM-F741Q", "SM-F741U", "SM-F741U1", "SM-F741W", + // Galaxy Z Flip7 + "SC-55F", "SCG35", "SM-F7660", "SM-F766B", "SM-F766N", "SM-F766Q", "SM-F766U", "SM-F766U1", "SM-F766W", "SM-F766Z", + // Galaxy Z Flip7 FE + "SM-F7610", "SM-F761B", "SM-F761N", "SM-F761U", "SM-F761U1", + // 心系天下 W23/W25 Flip + "SM-W7023", "SM-W7025" ) // Samsung foldable model prefixes private val SAMSUNG_FOLDABLE_PREFIXES = listOf( "SM-F9", // Galaxy Z Fold series - "SM-F7" // Galaxy Z Flip series + "SM-F7", // Galaxy Z Flip series + "SM-W70" // 心系天下 W series Flip ) // Google foldable models private val GOOGLE_FOLDABLE_MODELS = setOf( "Pixel Fold", - "Pixel 9 Pro Fold" + "Pixel 9 Pro Fold", + "Pixel 10 Pro Fold" ) // Motorola foldable models private val MOTOROLA_FOLDABLE_MODELS = setOf( - "XT2323-3", // razr 40 Ultra - "XT2321-2", // razr 40 - "XT2451-4", // razr+ 2024 - "XT2251-1", // razr 2022 - "XT2451-3" // razr 2024 + // razr 40 series + "XT2323-3", // moto razr 40 + "XT2321-2", // moto razr 40 Ultra + // razr 50 series + "XT2451-4", // moto razr 50 + "XT2453-2", // motorola razr 50 + // razr 60 series + "XT2551-3", // motorola razr 60 ultra + // razr 2022 + "XT2251-1", + // razr Japan models + "M-51E", // motorola razr 50d + "M-51F" // motorola razr 60d ) // ZTE/Nubia foldable models private val ZTE_FOLDABLE_MODELS = setOf( - "NX732J", // nubia Flip 5G - "NX724J" // nubia Flip + "NX732J", // nubia Flip 2 5G + "NX724J", // nubia Flip 5G + "Z9900S", // nubia Fold + "A502ZT", // nubia Fold (carrier) + "A304ZT", // Libero Flip + "Z8900CA" // nubia Flip 2 5G + ) + + // Tecno foldable models + private val TECNO_FOLDABLE_MODELS = setOf( + "TECNO-AD10", "TECNO AD10", // PHANTOM V Fold + "TECNO-AE10", "TECNO AE10", // PHANTOM V Fold2 5G + "TECNO-AD11", "TECNO AD11", // PHANTOM V Flip 5G + "TECNO-AE11", "TECNO AE11" // PHANTOM V Flip2 5G + ) + + // Infinix foldable models + private val INFINIX_FOLDABLE_MODELS = setOf( + "Infinix-X6962", "Infinix X6962" // ZERO Flip + ) + + // Royole foldable models + private val ROYOLE_FOLDABLE_MODELS = setOf( + "RY1205" // VERTU Ayxta Fold 3 + ) + + // Honor foldable models + private val HONOR_FOLDABLE_MODELS = setOf( + "VER-N49", // HONOR Magic V2 + "VER-N49DP", // PORSCHE DESIGN HONOR Magic V2 RSR + "FCP-N49", // HONOR Magic V3 + "MBH-N49", // HONOR Magic V5 + "FRI-NX9" // HONOR Magic Vs + ) + + // Vertu foldable models + private val VERTU_FOLDABLE_MODELS = setOf( + "VTL-202302" // METAFLIP ) } @@ -338,6 +422,61 @@ class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEven return ZTE_FOLDABLE_MODELS.contains(model) } + /** + * Check if the device is a Tecno foldable + */ + private fun isTecnoFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "TECNO") return false + + val model = Build.MODEL.uppercase() + return TECNO_FOLDABLE_MODELS.any { model.contains(it.uppercase()) } + } + + /** + * Check if the device is an Infinix foldable + */ + private fun isInfinixFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "INFINIX") return false + + val model = Build.MODEL.uppercase() + return INFINIX_FOLDABLE_MODELS.any { model.contains(it.uppercase()) } + } + + /** + * Check if the device is a Royole foldable + */ + private fun isRoyoleFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "ROYOLE") return false + + val model = Build.MODEL.uppercase() + return ROYOLE_FOLDABLE_MODELS.contains(model) + } + + /** + * Check if the device is an Honor foldable + */ + private fun isHonorFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "HONOR") return false + + val model = Build.MODEL.uppercase() + return HONOR_FOLDABLE_MODELS.contains(model) + } + + /** + * Check if the device is a Vertu foldable + */ + private fun isVertuFoldable(): Boolean { + val manufacturer = Build.MANUFACTURER.uppercase() + if (manufacturer != "VERTU") return false + + val model = Build.MODEL.uppercase() + return VERTU_FOLDABLE_MODELS.contains(model) + } + /** * Get cached foldable status from PreferenceManager */ @@ -378,7 +517,12 @@ class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEven isSamsungFoldable() || isGoogleFoldable() || isMotorolaFoldable() || - isZteFoldable() + isZteFoldable() || + isTecnoFoldable() || + isInfinixFoldable() || + isRoyoleFoldable() || + isHonorFoldable() || + isVertuFoldable() // Cache the result return isFoldable From b79b0464547553571d13ebeb68edad2b298b6fac Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 10:53:39 +0800 Subject: [PATCH 05/12] fix: correct fetchRecord return type in CloudKitModule Change return type from non-existent Variant_NullType_RecordResult to Promise to match HybridCloudKitModuleSpec interface. Co-Authored-By: Claude Opus 4.5 --- .../java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt b/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt index a32de2b..b1656a2 100644 --- a/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt +++ b/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt @@ -1,7 +1,6 @@ package com.margelo.nitro.cloudkitmodule import com.facebook.proguard.annotations.DoNotStrip -import com.margelo.nitro.core.NullType import com.margelo.nitro.core.Promise @DoNotStrip @@ -30,8 +29,8 @@ class CloudKitModule : HybridCloudKitModuleSpec() { ) } - override fun fetchRecord(params: FetchRecordParams): Promise { - return Promise.resolved(Variant_NullType_RecordResult.First(NullType.NULL)) + override fun fetchRecord(params: FetchRecordParams): Promise { + return Promise.resolved(null) } override fun deleteRecord(params: DeleteRecordParams): Promise { From 731517d18925cf6e0d89ff2fd73c96f89fb77254 Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 10:53:53 +0800 Subject: [PATCH 06/12] chore: upgrade react-native-nitro-modules to 0.33.2 Pin exact version (no caret prefix) across all subprojects: - native-modules/* - native-views/* - example/react-native - scripts/nitro/template - scripts/nitro-view/template - root package.json Co-Authored-By: Claude Opus 4.5 --- example/react-native/package.json | 2 +- .../package.json | 4 +- .../package.json | 4 +- .../react-native-device-utils/package.json | 4 +- .../package.json | 4 +- .../react-native-keychain-module/package.json | 4 +- .../react-native-skeleton/package.json | 4 +- package.json | 4 +- scripts/nitro-view/template/package.json | 4 +- scripts/nitro/template/package.json | 4 +- yarn.lock | 42 ++++++++++++------- 11 files changed, 45 insertions(+), 35 deletions(-) diff --git a/example/react-native/package.json b/example/react-native/package.json index 47a8049..861b125 100644 --- a/example/react-native/package.json +++ b/example/react-native/package.json @@ -42,7 +42,7 @@ "eslint": "^8.19.0", "jest": "^29.6.3", "prettier": "2.8.8", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "react-test-renderer": "19.2.0", "typescript": "^5.8.3" }, diff --git a/native-modules/react-native-check-biometric-auth-changed/package.json b/native-modules/react-native-check-biometric-auth-changed/package.json index 86aa6dd..912be80 100644 --- a/native-modules/react-native-check-biometric-auth-changed/package.json +++ b/native-modules/react-native-check-biometric-auth-changed/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "^0.31.10" + "react-native-nitro-modules": "0.33.2" }, "react-native-builder-bob": { "source": "src", diff --git a/native-modules/react-native-cloud-kit-module/package.json b/native-modules/react-native-cloud-kit-module/package.json index 0f92054..0b7d406 100644 --- a/native-modules/react-native-cloud-kit-module/package.json +++ b/native-modules/react-native-cloud-kit-module/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "^0.31.10" + "react-native-nitro-modules": "0.33.2" }, "react-native-builder-bob": { "source": "src", diff --git a/native-modules/react-native-device-utils/package.json b/native-modules/react-native-device-utils/package.json index b0f3b39..3dd76bf 100644 --- a/native-modules/react-native-device-utils/package.json +++ b/native-modules/react-native-device-utils/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "^0.31.10" + "react-native-nitro-modules": "0.33.2" }, "react-native-builder-bob": { "source": "src", diff --git a/native-modules/react-native-get-random-values/package.json b/native-modules/react-native-get-random-values/package.json index a961170..f614c0c 100644 --- a/native-modules/react-native-get-random-values/package.json +++ b/native-modules/react-native-get-random-values/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "^0.31.10" + "react-native-nitro-modules": "0.33.2" }, "react-native-builder-bob": { "source": "src", diff --git a/native-modules/react-native-keychain-module/package.json b/native-modules/react-native-keychain-module/package.json index 12634d1..0cfa4c8 100644 --- a/native-modules/react-native-keychain-module/package.json +++ b/native-modules/react-native-keychain-module/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "^0.31.10" + "react-native-nitro-modules": "0.33.2" }, "react-native-builder-bob": { "source": "src", diff --git a/native-views/react-native-skeleton/package.json b/native-views/react-native-skeleton/package.json index d8c2bc0..9ff854e 100644 --- a/native-views/react-native-skeleton/package.json +++ b/native-views/react-native-skeleton/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "0.31.10" + "react-native-nitro-modules": "0.33.2" }, "packageManager": "yarn@4.11.0", "react-native-builder-bob": { diff --git a/package.json b/package.json index 54247f5..7c23745 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -50,6 +50,6 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "^0.31.10" + "react-native-nitro-modules": "0.33.2" } } diff --git a/scripts/nitro-view/template/package.json b/scripts/nitro-view/template/package.json index cc29367..e27462a 100644 --- a/scripts/nitro-view/template/package.json +++ b/scripts/nitro-view/template/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "0.31.10" + "react-native-nitro-modules": "0.33.2" }, "packageManager": "yarn@4.11.0", "react-native-builder-bob": { diff --git a/scripts/nitro/template/package.json b/scripts/nitro/template/package.json index a4b3622..2ce716b 100644 --- a/scripts/nitro/template/package.json +++ b/scripts/nitro/template/package.json @@ -82,7 +82,7 @@ "react": "19.2.0", "react-native": "0.83.0", "react-native-builder-bob": "^0.40.13", - "react-native-nitro-modules": "0.31.10", + "react-native-nitro-modules": "0.33.2", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" @@ -90,7 +90,7 @@ "peerDependencies": { "react": "*", "react-native": "*", - "react-native-nitro-modules": "^0.31.10" + "react-native-nitro-modules": "0.33.2" }, "react-native-builder-bob": { "source": "src", diff --git a/yarn.lock b/yarn.lock index ebbb3e8..8f83aa6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2769,7 +2769,7 @@ __metadata: prettier: "npm:2.8.8" react: "npm:19.2.0" react-native: "npm:0.83.0" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" react-native-safe-area-context: "npm:^5.5.2" react-test-renderer: "npm:19.2.0" typescript: "npm:^5.8.3" @@ -2802,14 +2802,14 @@ __metadata: react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.31.10 + react-native-nitro-modules: 0.33.2 languageName: unknown linkType: soft @@ -2871,14 +2871,14 @@ __metadata: react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.31.10 + react-native-nitro-modules: 0.33.2 languageName: unknown linkType: soft @@ -2907,14 +2907,14 @@ __metadata: react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.31.10 + react-native-nitro-modules: 0.33.2 languageName: unknown linkType: soft @@ -2943,14 +2943,14 @@ __metadata: react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.31.10 + react-native-nitro-modules: 0.33.2 languageName: unknown linkType: soft @@ -2979,14 +2979,14 @@ __metadata: react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.31.10 + react-native-nitro-modules: 0.33.2 languageName: unknown linkType: soft @@ -3015,14 +3015,14 @@ __metadata: react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.31.10 + react-native-nitro-modules: 0.33.2 languageName: unknown linkType: soft @@ -3084,14 +3084,14 @@ __metadata: react: "npm:19.2.0" react-native: "npm:0.83.0" react-native-builder-bob: "npm:^0.40.13" - react-native-nitro-modules: "npm:0.31.10" + react-native-nitro-modules: "npm:0.33.2" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: 0.31.10 + react-native-nitro-modules: 0.33.2 languageName: unknown linkType: soft @@ -10661,7 +10661,17 @@ __metadata: languageName: node linkType: hard -"react-native-nitro-modules@npm:0.31.10, react-native-nitro-modules@npm:^0.31.10": +"react-native-nitro-modules@npm:0.33.2": + version: 0.33.2 + resolution: "react-native-nitro-modules@npm:0.33.2" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10/fece339c9f69b256d4e18e6fbf29bc52a16e2e8ea7e70551d8265dbaf455402a67fd8ca9f4e8abe5b6e6d3e33bf6c598d4e980dbbed00a3b791f6fa49c98be17 + languageName: node + linkType: hard + +"react-native-nitro-modules@npm:^0.31.10": version: 0.31.10 resolution: "react-native-nitro-modules@npm:0.31.10" peerDependencies: From 92b445abbe0302c55d6f71519e15e6e6b05c4ec2 Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 11:02:54 +0800 Subject: [PATCH 07/12] Update Podfile.lock --- example/react-native/ios/Podfile.lock | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/example/react-native/ios/Podfile.lock b/example/react-native/ios/Podfile.lock index fc24e13..db63084 100644 --- a/example/react-native/ios/Podfile.lock +++ b/example/react-native/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - BackgroundThread (1.1.11): + - BackgroundThread (1.1.14): - boost - DoubleConversion - fast_float @@ -28,7 +28,7 @@ PODS: - SocketRocket - Yoga - boost (1.84.0) - - CloudKitModule (1.1.11): + - CloudKitModule (1.1.14): - boost - DoubleConversion - fast_float @@ -66,7 +66,7 @@ PODS: - hermes-engine (0.14.0): - hermes-engine/Pre-built (= 0.14.0) - hermes-engine/Pre-built (0.14.0) - - KeychainModule (1.1.11): + - KeychainModule (1.1.14): - boost - DoubleConversion - fast_float @@ -96,7 +96,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - NitroModules (0.31.10): + - NitroModules (0.33.2): - boost - DoubleConversion - fast_float @@ -2653,7 +2653,7 @@ PODS: - React-perflogger (= 0.83.0) - React-utils (= 0.83.0) - SocketRocket - - ReactNativeCheckBiometricAuthChanged (1.1.11): + - ReactNativeCheckBiometricAuthChanged (1.1.14): - boost - DoubleConversion - fast_float @@ -2683,7 +2683,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - ReactNativeDeviceUtils (1.1.11): + - ReactNativeDeviceUtils (1.1.14): - boost - DoubleConversion - fast_float @@ -2713,7 +2713,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - ReactNativeGetRandomValues (1.1.11): + - ReactNativeGetRandomValues (1.1.14): - boost - DoubleConversion - fast_float @@ -2743,7 +2743,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - ReactNativeLiteCard (1.1.11): + - ReactNativeLiteCard (1.1.14): - boost - DoubleConversion - fast_float @@ -2771,7 +2771,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - Skeleton (1.1.11): + - Skeleton (1.1.14): - boost - DoubleConversion - fast_float @@ -3077,17 +3077,17 @@ EXTERNAL SOURCES: :path: "../../../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - BackgroundThread: d6bedf61338886caa616744dc1e4aa77656dc285 + BackgroundThread: 2f51ad2b9ac5c8dc8b873295cb4fa0b77371df55 boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 - CloudKitModule: febc66c8e919ad7f2f6e789af621dfaa0655e103 + CloudKitModule: 4a18e7a56a6f7880c10d4bec047b1079ffba1856 DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 FBLazyVector: a293a88992c4c33f0aee184acab0b64a08ff9458 fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 hermes-engine: 70fdc9d0bb0d8532e0411dcb21e53ce5a160960a - KeychainModule: 014ea2c49f4faa006a6e08b0ec6671875e830654 - NitroModules: 5bc319d441f4983894ea66b1d392c519536e6d23 + KeychainModule: b3a302819c0c8503a8a2b7062da406d67738974a + NitroModules: 11bba9d065af151eae51e38a6425e04c3b223ff3 RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: 2b70c6e3abe00396cefd8913efbf6a2db01a2b36 RCTRequired: f3540eee8094231581d40c5c6d41b0f170237a81 @@ -3158,11 +3158,11 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: ebcf3a78dc1bcdf054c9e8d309244bade6b31568 ReactCodegen: 554b421c45b7df35ac791da1b734335470b55fcc ReactCommon: 424cc34cf5055d69a3dcf02f3436481afb8b0f6f - ReactNativeCheckBiometricAuthChanged: 39255aa18891d558cb015483cc76bd7a4dc85df8 - ReactNativeDeviceUtils: adf7b3b1acc437360f7e2e13bcf5b6b74d8da0f8 - ReactNativeGetRandomValues: 1f4deca887951794a2cd3e85276c18bb944ec315 - ReactNativeLiteCard: 9b360619d69533b5e9aec940d3cdfb0d0c157f3a - Skeleton: b63a360c1f9f0c60e7938399d99bf25e151d6a46 + ReactNativeCheckBiometricAuthChanged: ff412b1570bb2825304cd3a56eb57f4893f42cb6 + ReactNativeDeviceUtils: dd5a737e99a2421e5836a283b4c9b93c91c01ffe + ReactNativeGetRandomValues: 4e4296a47967879ceba43a23fb6f737bd390accf + ReactNativeLiteCard: a956217791416e6ae0ce9166d4db1d0aad8f733c + Skeleton: aaeb4a2f3825df704a8b82dddf0329972d8c94ef SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: 6ca93c8c13f56baeec55eb608577619b17a4d64e From 797bcf8d88e089ecd0bb3565fe9074fc9d55099b Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 11:03:39 +0800 Subject: [PATCH 08/12] fix: correct fetchRecord return type in iOS CloudKitModule Change return type from Variant_NullType_RecordResult to Promise to match HybridCloudKitModuleSpec interface. Co-Authored-By: Claude Opus 4.5 --- .../ios/CloudKitModule.swift | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift b/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift index 2ba3063..f6a2b93 100644 --- a/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift +++ b/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift @@ -76,7 +76,7 @@ class CloudKitModule: HybridCloudKitModuleSpec { // MARK: - Fetch Record - public func fetchRecord(params: FetchRecordParams) throws -> NitroModules.Promise { + public func fetchRecord(params: FetchRecordParams) throws -> Promise { return Promise.async { let ckRecordID = CKRecord.ID(recordName: params.recordID) @@ -88,18 +88,16 @@ class CloudKitModule: HybridCloudKitModuleSpec { let createdAt = Int64((record.creationDate?.timeIntervalSince1970 ?? 0) * 1000) let modifiedAt = Int64((record.modificationDate?.timeIntervalSince1970 ?? 0) * 1000) - let result = Variant_NullType_RecordResult.second( - RecordResult( - recordID: record.recordID.recordName, - recordType: record.recordType, - data: data, - meta: meta, - createdAt: Double(createdAt), - modifiedAt: Double(modifiedAt)) + return RecordResult( + recordID: record.recordID.recordName, + recordType: record.recordType, + data: data, + meta: meta, + createdAt: Double(createdAt), + modifiedAt: Double(modifiedAt) ) - return result } catch let error as CKError where error.code == .unknownItem { - return Variant_NullType_RecordResult.first(NullType.null) + return nil } } } From b0dfc0abe3a374ee97cb4e0d64ce1e0bc453eaea Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 11:06:53 +0800 Subject: [PATCH 09/12] patch version --- native-modules/react-native-background-thread/package.json | 2 +- .../react-native-check-biometric-auth-changed/package.json | 2 +- native-modules/react-native-cloud-kit-module/package.json | 2 +- native-modules/react-native-device-utils/package.json | 2 +- native-modules/react-native-get-random-values/package.json | 2 +- native-modules/react-native-keychain-module/package.json | 2 +- native-modules/react-native-lite-card/package.json | 2 +- native-views/react-native-skeleton/package.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/native-modules/react-native-background-thread/package.json b/native-modules/react-native-background-thread/package.json index ab9f217..33ba1c5 100644 --- a/native-modules/react-native-background-thread/package.json +++ b/native-modules/react-native-background-thread/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-background-thread", - "version": "1.1.14", + "version": "1.1.15", "description": "react-native-background-thread", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-check-biometric-auth-changed/package.json b/native-modules/react-native-check-biometric-auth-changed/package.json index 912be80..de601dc 100644 --- a/native-modules/react-native-check-biometric-auth-changed/package.json +++ b/native-modules/react-native-check-biometric-auth-changed/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-check-biometric-auth-changed", - "version": "1.1.14", + "version": "1.1.15", "description": "react-native-check-biometric-auth-changed", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-cloud-kit-module/package.json b/native-modules/react-native-cloud-kit-module/package.json index 0b7d406..18ba7ea 100644 --- a/native-modules/react-native-cloud-kit-module/package.json +++ b/native-modules/react-native-cloud-kit-module/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-cloud-kit-module", - "version": "1.1.14", + "version": "1.1.15", "description": "react-native-cloud-kit-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-device-utils/package.json b/native-modules/react-native-device-utils/package.json index 3dd76bf..d8f51c0 100644 --- a/native-modules/react-native-device-utils/package.json +++ b/native-modules/react-native-device-utils/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-device-utils", - "version": "1.1.14", + "version": "1.1.15", "description": "react-native-device-utils", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-get-random-values/package.json b/native-modules/react-native-get-random-values/package.json index f614c0c..9077b8e 100644 --- a/native-modules/react-native-get-random-values/package.json +++ b/native-modules/react-native-get-random-values/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-get-random-values", - "version": "1.1.14", + "version": "1.1.15", "description": "react-native-get-random-values", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-keychain-module/package.json b/native-modules/react-native-keychain-module/package.json index 0cfa4c8..9292476 100644 --- a/native-modules/react-native-keychain-module/package.json +++ b/native-modules/react-native-keychain-module/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-keychain-module", - "version": "1.1.14", + "version": "1.1.15", "description": "react-native-keychain-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-lite-card/package.json b/native-modules/react-native-lite-card/package.json index dcc6c57..dcf10c4 100644 --- a/native-modules/react-native-lite-card/package.json +++ b/native-modules/react-native-lite-card/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-lite-card", - "version": "1.1.14", + "version": "1.1.15", "description": "lite card", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-views/react-native-skeleton/package.json b/native-views/react-native-skeleton/package.json index 9ff854e..4210a08 100644 --- a/native-views/react-native-skeleton/package.json +++ b/native-views/react-native-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-skeleton", - "version": "1.1.14", + "version": "1.1.15", "description": "react-native-skeleton", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", From 93a70855c4f8f839f66507d8027b58269e0619de Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 11:21:47 +0800 Subject: [PATCH 10/12] fix: use Variant_NullType_RecordResult for fetchRecord return type Update both iOS and Android CloudKitModule implementations to use Variant_NullType_RecordResult instead of optional types, matching the nitrogen 0.31.10 generated spec. Co-Authored-By: Claude Opus 4.5 --- .../com/margelo/nitro/cloudkitmodule/CloudKitModule.kt | 5 +++-- .../ios/CloudKitModule.swift | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt b/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt index b1656a2..35dcc35 100644 --- a/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt +++ b/native-modules/react-native-cloud-kit-module/android/src/main/java/com/margelo/nitro/cloudkitmodule/CloudKitModule.kt @@ -1,6 +1,7 @@ package com.margelo.nitro.cloudkitmodule import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.core.NullType import com.margelo.nitro.core.Promise @DoNotStrip @@ -29,8 +30,8 @@ class CloudKitModule : HybridCloudKitModuleSpec() { ) } - override fun fetchRecord(params: FetchRecordParams): Promise { - return Promise.resolved(null) + override fun fetchRecord(params: FetchRecordParams): Promise { + return Promise.resolved(Variant_NullType_RecordResult.create(NullType.NULL)) } override fun deleteRecord(params: DeleteRecordParams): Promise { diff --git a/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift b/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift index f6a2b93..7c34943 100644 --- a/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift +++ b/native-modules/react-native-cloud-kit-module/ios/CloudKitModule.swift @@ -76,7 +76,7 @@ class CloudKitModule: HybridCloudKitModuleSpec { // MARK: - Fetch Record - public func fetchRecord(params: FetchRecordParams) throws -> Promise { + public func fetchRecord(params: FetchRecordParams) throws -> Promise { return Promise.async { let ckRecordID = CKRecord.ID(recordName: params.recordID) @@ -88,16 +88,16 @@ class CloudKitModule: HybridCloudKitModuleSpec { let createdAt = Int64((record.creationDate?.timeIntervalSince1970 ?? 0) * 1000) let modifiedAt = Int64((record.modificationDate?.timeIntervalSince1970 ?? 0) * 1000) - return RecordResult( + return Variant_NullType_RecordResult.second(RecordResult( recordID: record.recordID.recordName, recordType: record.recordType, data: data, meta: meta, createdAt: Double(createdAt), modifiedAt: Double(modifiedAt) - ) + )) } catch let error as CKError where error.code == .unknownItem { - return nil + return Variant_NullType_RecordResult.first(NullType.null) } } } From faf69d6207598519f5bd76d1974586e6b0196516 Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 11:24:03 +0800 Subject: [PATCH 11/12] Update Podfile.lock --- example/react-native/ios/Podfile.lock | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/example/react-native/ios/Podfile.lock b/example/react-native/ios/Podfile.lock index db63084..d7f4097 100644 --- a/example/react-native/ios/Podfile.lock +++ b/example/react-native/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - BackgroundThread (1.1.14): + - BackgroundThread (1.1.15): - boost - DoubleConversion - fast_float @@ -28,7 +28,7 @@ PODS: - SocketRocket - Yoga - boost (1.84.0) - - CloudKitModule (1.1.14): + - CloudKitModule (1.1.15): - boost - DoubleConversion - fast_float @@ -66,7 +66,7 @@ PODS: - hermes-engine (0.14.0): - hermes-engine/Pre-built (= 0.14.0) - hermes-engine/Pre-built (0.14.0) - - KeychainModule (1.1.14): + - KeychainModule (1.1.15): - boost - DoubleConversion - fast_float @@ -2653,7 +2653,7 @@ PODS: - React-perflogger (= 0.83.0) - React-utils (= 0.83.0) - SocketRocket - - ReactNativeCheckBiometricAuthChanged (1.1.14): + - ReactNativeCheckBiometricAuthChanged (1.1.15): - boost - DoubleConversion - fast_float @@ -2683,7 +2683,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - ReactNativeDeviceUtils (1.1.14): + - ReactNativeDeviceUtils (1.1.15): - boost - DoubleConversion - fast_float @@ -2713,7 +2713,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - ReactNativeGetRandomValues (1.1.14): + - ReactNativeGetRandomValues (1.1.15): - boost - DoubleConversion - fast_float @@ -2743,7 +2743,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - ReactNativeLiteCard (1.1.14): + - ReactNativeLiteCard (1.1.15): - boost - DoubleConversion - fast_float @@ -2771,7 +2771,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - Skeleton (1.1.14): + - Skeleton (1.1.15): - boost - DoubleConversion - fast_float @@ -3077,16 +3077,16 @@ EXTERNAL SOURCES: :path: "../../../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - BackgroundThread: 2f51ad2b9ac5c8dc8b873295cb4fa0b77371df55 + BackgroundThread: 8bfdbb6081771366de5e5e2b588aad1beafea9be boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 - CloudKitModule: 4a18e7a56a6f7880c10d4bec047b1079ffba1856 + CloudKitModule: a7596fae8e1e2d05bd0ba2fa4d4ad90b5e93ea5a DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 FBLazyVector: a293a88992c4c33f0aee184acab0b64a08ff9458 fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 hermes-engine: 70fdc9d0bb0d8532e0411dcb21e53ce5a160960a - KeychainModule: b3a302819c0c8503a8a2b7062da406d67738974a + KeychainModule: 7a82d9b61fbd70183fdb991384e6a99eff8ac502 NitroModules: 11bba9d065af151eae51e38a6425e04c3b223ff3 RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: 2b70c6e3abe00396cefd8913efbf6a2db01a2b36 @@ -3158,11 +3158,11 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: ebcf3a78dc1bcdf054c9e8d309244bade6b31568 ReactCodegen: 554b421c45b7df35ac791da1b734335470b55fcc ReactCommon: 424cc34cf5055d69a3dcf02f3436481afb8b0f6f - ReactNativeCheckBiometricAuthChanged: ff412b1570bb2825304cd3a56eb57f4893f42cb6 - ReactNativeDeviceUtils: dd5a737e99a2421e5836a283b4c9b93c91c01ffe - ReactNativeGetRandomValues: 4e4296a47967879ceba43a23fb6f737bd390accf - ReactNativeLiteCard: a956217791416e6ae0ce9166d4db1d0aad8f733c - Skeleton: aaeb4a2f3825df704a8b82dddf0329972d8c94ef + ReactNativeCheckBiometricAuthChanged: 5757aec913dee03c7d488eebb6b05a91ff774e61 + ReactNativeDeviceUtils: 2372c7f86169033f39b524b0bfc28323a2cf6bdc + ReactNativeGetRandomValues: 60a36d2a7e0ced4e37bbbc9faa98e11f27655518 + ReactNativeLiteCard: d59be2b082bc3e7ef452095042c1e6b5483ab210 + Skeleton: af32eaa6d321cf4f3266cf408dadec752dfb8e1d SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: 6ca93c8c13f56baeec55eb608577619b17a4d64e From e368e45eead0a8ec611945e5028ec1186fef433c Mon Sep 17 00:00:00 2001 From: huhuanming Date: Thu, 29 Jan 2026 11:26:41 +0800 Subject: [PATCH 12/12] version patch --- native-modules/react-native-background-thread/package.json | 2 +- .../react-native-check-biometric-auth-changed/package.json | 2 +- native-modules/react-native-cloud-kit-module/package.json | 2 +- native-modules/react-native-device-utils/package.json | 2 +- native-modules/react-native-get-random-values/package.json | 2 +- native-modules/react-native-keychain-module/package.json | 2 +- native-modules/react-native-lite-card/package.json | 2 +- native-views/react-native-skeleton/package.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/native-modules/react-native-background-thread/package.json b/native-modules/react-native-background-thread/package.json index 33ba1c5..1105833 100644 --- a/native-modules/react-native-background-thread/package.json +++ b/native-modules/react-native-background-thread/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-background-thread", - "version": "1.1.15", + "version": "1.1.16", "description": "react-native-background-thread", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-check-biometric-auth-changed/package.json b/native-modules/react-native-check-biometric-auth-changed/package.json index de601dc..89cd2e7 100644 --- a/native-modules/react-native-check-biometric-auth-changed/package.json +++ b/native-modules/react-native-check-biometric-auth-changed/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-check-biometric-auth-changed", - "version": "1.1.15", + "version": "1.1.16", "description": "react-native-check-biometric-auth-changed", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-cloud-kit-module/package.json b/native-modules/react-native-cloud-kit-module/package.json index 18ba7ea..a1a842b 100644 --- a/native-modules/react-native-cloud-kit-module/package.json +++ b/native-modules/react-native-cloud-kit-module/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-cloud-kit-module", - "version": "1.1.15", + "version": "1.1.16", "description": "react-native-cloud-kit-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-device-utils/package.json b/native-modules/react-native-device-utils/package.json index d8f51c0..3d42c2d 100644 --- a/native-modules/react-native-device-utils/package.json +++ b/native-modules/react-native-device-utils/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-device-utils", - "version": "1.1.15", + "version": "1.1.16", "description": "react-native-device-utils", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-get-random-values/package.json b/native-modules/react-native-get-random-values/package.json index 9077b8e..64ca192 100644 --- a/native-modules/react-native-get-random-values/package.json +++ b/native-modules/react-native-get-random-values/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-get-random-values", - "version": "1.1.15", + "version": "1.1.16", "description": "react-native-get-random-values", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-keychain-module/package.json b/native-modules/react-native-keychain-module/package.json index 9292476..cac8464 100644 --- a/native-modules/react-native-keychain-module/package.json +++ b/native-modules/react-native-keychain-module/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-keychain-module", - "version": "1.1.15", + "version": "1.1.16", "description": "react-native-keychain-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-modules/react-native-lite-card/package.json b/native-modules/react-native-lite-card/package.json index dcf10c4..6c19f8f 100644 --- a/native-modules/react-native-lite-card/package.json +++ b/native-modules/react-native-lite-card/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-lite-card", - "version": "1.1.15", + "version": "1.1.16", "description": "lite card", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", diff --git a/native-views/react-native-skeleton/package.json b/native-views/react-native-skeleton/package.json index 4210a08..a65d37f 100644 --- a/native-views/react-native-skeleton/package.json +++ b/native-views/react-native-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-skeleton", - "version": "1.1.15", + "version": "1.1.16", "description": "react-native-skeleton", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts",