From bf1cd56bdedb98af3f01e29c5c1b02dfadca491e Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 10 Sep 2026 10:34:40 +0800 Subject: [PATCH 1/3] fix: preserve Android images during updates and navigation --- .../react-native-image/android/build.gradle | 2 + .../margelo/nitro/onekeyimage/OneKeyImage.kt | 61 +++++--- .../OneKeyBlockieAvatarLoaderTest.kt | 5 + .../onekeyimage/OneKeyImageLifecycleTest.kt | 136 ++++++++++++++++++ .../nitro/onekeyimage/PngOnlyAvifDecoder.kt | 22 +++ .../android/build.gradle | 3 + .../onekey/nativelist/NativeListRowUpdates.kt | 26 ++++ .../onekey/nativelist/NativeListRowView.kt | 46 +++++- .../nativelist/NativeListRowBindingTest.kt | 128 +++++++++++++++++ .../nativelist/NativeListRowUpdatesTest.kt | 53 +++++++ .../onekey/nativelist/PngOnlyAvifDecoder.kt | 22 +++ 11 files changed, 483 insertions(+), 21 deletions(-) create mode 100644 native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt create mode 100644 native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt create mode 100644 native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowUpdates.kt create mode 100644 native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt create mode 100644 native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt create mode 100644 native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt diff --git a/native-views/react-native-image/android/build.gradle b/native-views/react-native-image/android/build.gradle index f6bed366..852dec71 100644 --- a/native-views/react-native-image/android/build.gradle +++ b/native-views/react-native-image/android/build.gradle @@ -64,6 +64,7 @@ android { sourceSets { main { java.srcDirs += ["generated/java", "generated/jni"] } } + testOptions { unitTests.includeAndroidResources = true } } repositories { mavenCentral(); google() } @@ -82,4 +83,5 @@ dependencies { implementation project(":react-native-nitro-modules") implementation project(":onekeyfe_react-native-skeleton") testImplementation "junit:junit:4.13.2" + testImplementation "org.robolectric:robolectric:4.16.1" } diff --git a/native-views/react-native-image/android/src/main/java/com/margelo/nitro/onekeyimage/OneKeyImage.kt b/native-views/react-native-image/android/src/main/java/com/margelo/nitro/onekeyimage/OneKeyImage.kt index 0f60f74d..95faa04b 100644 --- a/native-views/react-native-image/android/src/main/java/com/margelo/nitro/onekeyimage/OneKeyImage.kt +++ b/native-views/react-native-image/android/src/main/java/com/margelo/nitro/onekeyimage/OneKeyImage.kt @@ -245,6 +245,12 @@ class HybridOneKeyImage(private val context: ThemedReactContext) : init { OneKeyImageGlideRegistry.ensureRegistered(context) hostView.updateSkeletonStyle() + installHostCallbacks() + applyContentFit() + applyVariant() + } + + private fun installHostCallbacks() { hostView.onReadyForRequest = { scheduleLoad() } hostView.onAttachmentChanged = { attached -> if (attached) { @@ -255,8 +261,6 @@ class HybridOneKeyImage(private val context: ThemedReactContext) : displayRunnable = null } } - applyContentFit() - applyVariant() } override fun afterUpdate() { @@ -276,21 +280,38 @@ class HybridOneKeyImage(private val context: ThemedReactContext) : override fun prepareForRecycle() { resetForReuse() + disposed = false + installHostCallbacks() } override fun onDropView() { - resetForReuse() disposed = true hostView.onReadyForRequest = null - hostView.onAttachmentChanged = null + cancelPendingCallbacks() + clearEventCallbacks() + hostView.autoplayEnabled = false + hostView.skeletonRequested = false + hostView.syncPlayback() + if (!usesApplicationRequestManager && hostView.isAttachedToWindow && hostView.drawable != null) { + // ScreenStack can still draw a dropped view during its removal transition. + // Keep the completed Glide target too: clearing it may recycle the bitmap. + hostView.onAttachmentChanged = { attached -> if (!attached) finishDrop() } + } else { + finishDrop() + } super.onDropView() } - override fun dispose() { - disposed = true - cancelCurrent(invalidateGeneration = true) + private fun finishDrop() { + resetForReuse() hostView.onReadyForRequest = null hostView.onAttachmentChanged = null + } + + override fun dispose() { + disposed = true + clearEventCallbacks() + finishDrop() super.dispose() } @@ -317,11 +338,7 @@ class HybridOneKeyImage(private val context: ThemedReactContext) : resizeWidth = null overscan = 1.1 loadingStrategy = OneKeyImageLoadingStrategy.STATIC - onLoadStart = null - onLoad = null - onDisplay = null - onError = null - onLoadEnd = null + clearEventCallbacks() suppressPropEffects = false requestActive = false displayState = DisplayState.LOADING @@ -553,6 +570,14 @@ class HybridOneKeyImage(private val context: ThemedReactContext) : } private fun cancelCurrent(invalidateGeneration: Boolean) { + cancelPendingCallbacks() + clearCurrentTarget() + requestActive = false + hostView.skeletonRequested = false + if (invalidateGeneration) generation++ + } + + private fun cancelPendingCallbacks() { loadRunnable?.let(hostView::removeCallbacks) loadRunnable = null displayRunnable?.let(hostView::removeCallbacks) @@ -560,10 +585,14 @@ class HybridOneKeyImage(private val context: ThemedReactContext) : pendingDisplayGeneration = null fallbackRunnable?.let(hostView::removeCallbacks) fallbackRunnable = null - clearCurrentTarget() - requestActive = false - hostView.skeletonRequested = false - if (invalidateGeneration) generation++ + } + + private fun clearEventCallbacks() { + onLoadStart = null + onLoad = null + onDisplay = null + onError = null + onLoadEnd = null } private fun clearCurrentTarget() { diff --git a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt index 64d5c04a..17e00c23 100644 --- a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt +++ b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt @@ -16,6 +16,9 @@ import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config import java.io.IOException import java.io.File import java.nio.file.Files @@ -26,6 +29,8 @@ import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicInteger +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [35]) class OneKeyBlockieAvatarLoaderTest { private val uri = "onekey-avatar://blockie/v1/0x1234" diff --git a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt new file mode 100644 index 00000000..f53796bf --- /dev/null +++ b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt @@ -0,0 +1,136 @@ +package com.margelo.nitro.onekeyimage + +import android.app.Activity +import android.graphics.Bitmap +import android.graphics.Color +import android.os.Looper +import android.widget.FrameLayout +import android.widget.ImageView +import com.bumptech.glide.request.target.Target +import com.facebook.react.bridge.BridgeReactContext +import com.facebook.react.uimanager.ThemedReactContext +import org.junit.After +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner +import org.robolectric.Shadows.shadowOf +import org.robolectric.annotation.Config +import java.io.File + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [35], shadows = [PngOnlyAvifDecoder::class]) +class OneKeyImageLifecycleTest { + private val controller = Robolectric.buildActivity(Activity::class.java) + private lateinit var container: FrameLayout + private lateinit var image: HybridOneKeyImage + private lateinit var source: File + + @Before + fun setUp() { + val activity = controller.setup().visible().get() + container = FrameLayout(activity) + activity.setContentView(container) + val context = ThemedReactContext(BridgeReactContext(activity.application), activity, "test", 1) + image = HybridOneKeyImage(context) + source = File.createTempFile("image-lifecycle", ".png", activity.cacheDir) + val bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888).apply { eraseColor(Color.GREEN) } + source.outputStream().use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) } + bitmap.recycle() + container.addView(image.view, FrameLayout.LayoutParams(32, 32)) + image.view.layout(0, 0, 32, 32) + } + + @After + fun tearDown() { + image.dispose() + controller.pause().stop().destroy() + source.delete() + } + + private fun loadImage() { + image.sourceUri = source.toURI().toString() + val deadline = System.nanoTime() + 10_000_000_000L + while ((image.view as ImageView).drawable == null && System.nanoTime() < deadline) { + shadowOf(Looper.getMainLooper()).idle() + Thread.sleep(10) + } + assertNotNull("The local image must finish decoding", (image.view as ImageView).drawable) + } + + private fun target(): Target<*>? = + HybridOneKeyImage::class.java.getDeclaredField("currentTarget").run { + isAccessible = true + get(image) as? Target<*> + } + + @Test + fun droppedImageRetainsItsGlideResourceUntilRemovalTransitionEnds() { + loadImage() + val drawable = (image.view as ImageView).drawable + val request = target()!!.request!! + container.startViewTransition(image.view) + container.removeView(image.view) + assertTrue(image.view.isAttachedToWindow) + + image.onDropView() + + assertSame(drawable, (image.view as ImageView).drawable) + assertFalse("Glide must still own the bitmap while it is drawn", request.isCleared) + container.endViewTransition(image.view) + assertFalse(image.view.isAttachedToWindow) + assertNull((image.view as ImageView).drawable) + assertTrue(request.isCleared) + assertNull(target()) + } + + @Test + fun detachedDropAndExplicitNativeOwnerDisposalReleaseImmediately() { + loadImage() + val request = target()!!.request!! + container.removeView(image.view) + image.onDropView() + assertTrue(request.isCleared) + assertNull((image.view as ImageView).drawable) + + image.prepareForRecycle() + image.usesApplicationRequestManager = true + container.addView(image.view, FrameLayout.LayoutParams(32, 32)) + image.view.layout(0, 0, 32, 32) + loadImage() + val nativeRequest = target()!!.request!! + image.onDropView() + assertTrue(nativeRequest.isCleared) + assertNull((image.view as ImageView).drawable) + } + + @Test + fun dropCancelsPendingLoadsAndRecyclingAllowsANewSource() { + var callbacks = 0 + image.onLoadStart = { callbacks++ } + image.onLoad = { _, _, _ -> callbacks++ } + image.onDisplay = { callbacks++ } + image.sourceUri = source.toURI().toString() + image.onDropView() + shadowOf(Looper.getMainLooper()).idle() + assertEquals(0, callbacks) + assertNull(target()) + + image.prepareForRecycle() + image.onLoad = { _, _, _ -> callbacks++ } + loadImage() + assertEquals(1, callbacks) + } + + @Test + fun sourceOrRecyclingKeyChangesStillClearThePreviousImageImmediately() { + loadImage() + image.recyclingKey = "another-account" + assertNull((image.view as ImageView).drawable) + loadImage() + image.sourceUri = null + assertNull((image.view as ImageView).drawable) + } +} diff --git a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt new file mode 100644 index 00000000..ec75299c --- /dev/null +++ b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt @@ -0,0 +1,22 @@ +package com.margelo.nitro.onekeyimage + +import org.robolectric.annotation.Implementation +import org.robolectric.annotation.Implements +import java.nio.ByteBuffer + +// PNG lifecycle tests do not load the Android-only AVIF JNI library on the JVM. +@Implements(className = "org.aomedia.avif.android.AvifDecoder", isInAndroidSdk = false) +class PngOnlyAvifDecoder { + companion object { + @JvmStatic + @Implementation + fun __staticInitializer__() = Unit + + @JvmStatic + @Implementation + fun isAvifImage(data: ByteBuffer): Boolean { + check(data.limit() >= 4 && data.getInt(0) == 0x89504E47.toInt()) { "Only PNG fixtures are supported" } + return false + } + } +} diff --git a/native-views/react-native-native-list/android/build.gradle b/native-views/react-native-native-list/android/build.gradle index a4796fa0..ca95d600 100644 --- a/native-views/react-native-native-list/android/build.gradle +++ b/native-views/react-native-native-list/android/build.gradle @@ -64,6 +64,7 @@ android { buildConfig true prefab true } + testOptions { unitTests.includeAndroidResources = true } buildTypes { release { @@ -102,4 +103,6 @@ dependencies { implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation project(":react-native-nitro-modules") implementation project(":onekeyfe_react-native-image") + testImplementation "junit:junit:4.13.2" + testImplementation "org.robolectric:robolectric:4.16.1" } diff --git a/native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowUpdates.kt b/native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowUpdates.kt new file mode 100644 index 00000000..3804afd0 --- /dev/null +++ b/native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowUpdates.kt @@ -0,0 +1,26 @@ +package com.margelo.nitro.nativelist + +import org.json.JSONObject + +/** Only text and tone inside existing subtitle slots may change without rebuilding an identity row. */ +internal fun canUpdateIdentitySubtitle(previous: NativeListItem, next: NativeListItem): Boolean { + if (previous.key != next.key || previous.type != "identity" || next.type != "identity") return false + + fun structure(item: NativeListItem): String? { + val data = JSONObject(item.content) + if (data.optString("presentation") != "accountSelector") return null + val segments = data.optJSONArray("subtitleSegments") ?: return null + if (segments.length() == 0) return null + for (index in 0 until segments.length()) { + val segment = segments.optJSONObject(index) ?: return null + segment.remove("text") + segment.remove("textSegments") + segment.remove("tone") + } + data.remove("accessibilityLabel") + return data.toString() + } + + val previousStructure = structure(previous) ?: return false + return previousStructure == structure(next) +} diff --git a/native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt b/native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt index 7821793d..47a713f1 100644 --- a/native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt +++ b/native-views/react-native-native-list/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt @@ -339,6 +339,9 @@ internal class NativeListRowView( private val selectorLineHeights = mutableMapOf() private val selectorFontSizes = mutableMapOf() private val selectorImages = mutableListOf() + private val identitySubtitleLabels = mutableListOf() + private var boundTheme: String? = null + private var boundOrientation: String? = null private var selectorHeight: Int? = null private val leadingImages = List(3) { OneKeyImageReusableView(reactContext) } private val leadingOverlayBackground = View(context) @@ -649,6 +652,24 @@ internal class NativeListRowView( checkboxState: (NativeListItem, NativeSelectionTarget?, String) -> String, useSourceScale: Boolean = false, ) { + val previous = tag as? NativeListItem + val sourceScale = item.usesSelectorSourceScale || useSourceScale + if ( + boundKey == item.key && previous != null && + boundTheme == theme?.toString() && currentLayout == layout && + boundOrientation == listOrientation && selectorUsesSourceScale == sourceScale && + identitySubtitleLabels.isNotEmpty() && canUpdateIdentitySubtitle(previous, item) + ) { + // Balance patches keep the same avatar and its in-flight/completed image request. + val segments = item.json.getJSONArray("subtitleSegments") + identitySubtitleLabels.forEachIndexed { index, label -> + bindIdentitySubtitleLabel(label, segments.getJSONObject(index), theme) + } + contentDescription = item.json.optString("accessibilityLabel", item.json.optString("title")) + bindSelection(item, theme, layout, itemIndex, selected, checkboxState) + applySelectorTypography(item) + return + } val shouldRestorePressed = touchPressed && boundKey == item.key invalidateCurrentBinding() bindingEpoch += 1 @@ -656,7 +677,9 @@ internal class NativeListRowView( touchPressed = shouldRestorePressed currentLayout = layout tag = item - selectorUsesSourceScale = item.usesSelectorSourceScale || useSourceScale + selectorUsesSourceScale = sourceScale + boundTheme = theme?.toString() + boundOrientation = listOrientation reorderActive = false leadingImages.forEach(OneKeyImageReusableView::prepareForReuse) secondaryImage.prepareForReuse() @@ -939,6 +962,7 @@ internal class NativeListRowView( } private fun resetViews() { + identitySubtitleLabels.clear() clipChildren = true clipToPadding = true selectorOriginalFontFeatures.forEach { (view, original) -> view.fontFeatureSettings = original } @@ -1442,17 +1466,15 @@ internal class NativeListRowView( line.addView(dot, LayoutParams(dp(4), dp(4)).apply { marginStart = dp(6); marginEnd = dp(6) }) } val label = TextView(context).apply { - text = segment.optString("text") typeface = NativeListFonts.regular(context) textSize = sp(14f) includeFontPadding = false maxLines = 1 ellipsize = TextUtils.TruncateAt.END - val toneKey = when (segment.optString("tone")) { "primary" -> "primaryText"; "disabled" -> "disabledText"; "caution" -> "caution"; "positive" -> "positive"; "negative" -> "negative"; else -> "secondaryText" } - setTextColor(color(theme, toneKey, if (toneKey == "caution") "#AB6400" else "#0000009B")) } TextViewCompat.setLineHeight(label, dp(20)) - applyValueSegments(label, segment.optJSONArray("textSegments"), 14, 20, false) + bindIdentitySubtitleLabel(label, segment, theme) + identitySubtitleLabels.add(label) line.addView(label, LayoutParams(LayoutParams.WRAP_CONTENT, dp(20))) } mainColumn.addView(line, 2, LayoutParams(LayoutParams.MATCH_PARENT, dp(20))) @@ -2311,6 +2333,20 @@ internal class NativeListRowView( applyValueSegments(trailingViews[0], item.json.optJSONArray("valueSegments")) } + private fun bindIdentitySubtitleLabel(label: TextView, segment: JSONObject, theme: JSONObject?) { + label.text = segment.optString("text") + val toneKey = when (segment.optString("tone")) { + "primary" -> "primaryText" + "disabled" -> "disabledText" + "caution" -> "caution" + "positive" -> "positive" + "negative" -> "negative" + else -> "secondaryText" + } + label.setTextColor(color(theme, toneKey, if (toneKey == "caution") "#AB6400" else "#0000009B")) + applyValueSegments(label, segment.optJSONArray("textSegments"), 14, 20, false) + } + // OneKey patch: preserve compact zero-count digits without changing their baseline. private fun applyValueSegments(view: TextView, segments: JSONArray?, fontSize: Int = 16, lineHeight: Int = 24, medium: Boolean = true) { if (segments == null || segments.length() == 0) return diff --git a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt new file mode 100644 index 00000000..ff68e41b --- /dev/null +++ b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt @@ -0,0 +1,128 @@ +package com.margelo.nitro.nativelist + +import android.app.Activity +import android.os.Looper +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.TextView +import com.facebook.react.bridge.BridgeReactContext +import com.facebook.react.uimanager.ThemedReactContext +import com.margelo.nitro.onekeyimage.OneKeyImageReusableView +import org.json.JSONObject +import org.junit.After +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner +import org.robolectric.Shadows.shadowOf +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [35], shadows = [PngOnlyAvifDecoder::class]) +class NativeListRowBindingTest { + private val controller = Robolectric.buildActivity(Activity::class.java) + private lateinit var row: NativeListRowView + + @Before + fun setUp() { + val activity = controller.setup().visible().get() + val context = ThemedReactContext(BridgeReactContext(activity.application), activity, "test", 1) + row = NativeListRowView(context) + val container = FrameLayout(activity) + activity.setContentView(container) + container.addView(row, FrameLayout.LayoutParams(400, 64)) + } + + @After + fun tearDown() { + row.dispose() + controller.pause().stop().destroy() + } + + private fun bind(item: NativeListItem, theme: JSONObject? = null) { + row.bind(item, theme, "linear", "vertical", 0, false, { _, _, fallback -> fallback }) + row.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(64, View.MeasureSpec.EXACTLY)) + row.layout(0, 0, 400, 64) + } + + private fun descendants(view: View): List = buildList { + add(view) + if (view is ViewGroup) for (index in 0 until view.childCount) addAll(descendants(view.getChildAt(index))) + } + + private fun avatar(): ImageView { + val reusable = descendants(row).filterIsInstance() + .first { it.visibility == View.VISIBLE } + return reusable.getChildAt(0) as ImageView + } + + private fun awaitAvatar() { + val deadline = System.nanoTime() + 10_000_000_000L + while (avatar().drawable == null && System.nanoTime() < deadline) { + shadowOf(Looper.getMainLooper()).idle() + Thread.sleep(10) + } + assertNotNull("The avatar must finish decoding", avatar().drawable) + } + + @Test + fun repeatedBalancePatchesKeepTheLoadedAvatarAndExistingTextViews() { + val theme = JSONObject("""{"disabledText":"#777777","secondaryText":"#999999"}""") + bind(accountRow(), theme) + awaitAvatar() + val imageView = avatar() + val drawable = imageView.drawable + val subtitle = descendants(row).filterIsInstance().first { it.text.toString() == "--" } + for (value in listOf("12.34", "12.56", "--", "1.25")) { + bind(accountRow(value), theme) + assertSame(imageView, avatar()) + assertSame("No placeholder between balance updates", drawable, imageView.drawable) + assertEquals(value, subtitle.text.toString()) + assertEquals(android.graphics.Color.parseColor(if (value == "--") "#777777" else "#999999"), subtitle.currentTextColor) + assertEquals("Account #1, $value", row.contentDescription) + shadowOf(Looper.getMainLooper()).idle() + assertSame("No asynchronous avatar reload", drawable, imageView.drawable) + } + } + + @Test + fun subtitlePatchWhileTheAvatarIsLoadingKeepsItsCompletionBindingValid() { + bind(accountRow()) + val epoch = row.bindingEpoch + bind(accountRow("12.34")) + assertEquals(epoch, row.bindingEpoch) + awaitAvatar() + assertEquals("Account #1, 12.34", row.contentDescription) + } + + @Test + fun changedAvatarAndRecycledRowCannotKeepStaleImages() { + bind(accountRow()) + awaitAvatar() + val next = JSONObject(accountRow("12.34").content) + next.getJSONObject("leading").getJSONObject("image") + .put("uri", "onekey-avatar://blockie/v1/0x5678") + bind(NativeListItem.parse(next)) + assertNull(avatar().drawable) + awaitAvatar() + row.recycle() + assertNull(avatar().drawable) + bind(NativeListItem.parse(next)) + awaitAvatar() + } + + @Test + fun themeChangesStillPerformFullBinding() { + bind(accountRow()) + val epoch = row.bindingEpoch + bind(accountRow("12.34"), JSONObject("""{"primaryText":"#FFFFFF","secondaryText":"#AAAAAA"}""")) + assertTrue(row.bindingEpoch > epoch) + val title = descendants(row).filterIsInstance().first { it.text.toString() == "Account #1" } + assertEquals(android.graphics.Color.WHITE, title.currentTextColor) + } +} diff --git a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt new file mode 100644 index 00000000..c28c3f39 --- /dev/null +++ b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt @@ -0,0 +1,53 @@ +package com.margelo.nitro.nativelist + +import org.json.JSONArray +import org.json.JSONObject +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +internal fun accountRow(value: String = "--"): NativeListItem = NativeListItem.parse(JSONObject(""" + {"key":"account-1","type":"identity","presentation":"accountSelector","height":64, + "title":"Account #1","accessibilityLabel":"Account #1, $value", + "leading":{"kind":"account","image":{"uri":"onekey-avatar://blockie/v1/0x1234"}}, + "subtitleSegments":[{"text":"$value","tone":"${if (value == "--") "disabled" else "secondary"}"},{"text":"0x1234","separatorBefore":true}]} +""")) + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [35]) +class NativeListRowUpdatesTest { + @Test + fun balanceAndRichTextChangesPreserveTheSameSubtitleSlotsWithoutMutatingRows() { + val previous = accountRow() + val next = accountRow("12.34") + next.json.getJSONArray("subtitleSegments").getJSONObject(0) + .put("textSegments", JSONArray("""[{"text":"0.0"},{"text":"4","style":"subscript"}]""")) + val rich = NativeListItem.parse(next.json) + assertTrue(canUpdateIdentitySubtitle(previous, rich)) + assertTrue(canUpdateIdentitySubtitle(rich, accountRow("12.56"))) + assertEquals("--", previous.json.getJSONArray("subtitleSegments").getJSONObject(0).getString("text")) + assertTrue(rich.json.getJSONArray("subtitleSegments").getJSONObject(0).has("textSegments")) + } + + @Test + fun identityImageActionsThemeRelatedFieldsAndUnknownChangesRequireFullBinding() { + val previous = accountRow() + val changes = listOf( + """{"key":"account-2"}""", """{"type":"action"}""", + """{"leading":{"kind":"account","image":{"uri":"different"}}}""", + """{"trailing":[{"kind":"icon","name":"PlusSmallOutline"}]}""", + """{"height":80}""", """{"presentation":"networkSelector"}""", + """{"revision":1}""", """{"disabled":true}""", """{"unknownField":1}""", + """{"subtitleSegments":[]}""", + """{"subtitleSegments":[{"text":"1"},{"text":"address","separatorBefore":false}]}""", + ) + for (change in changes) { + val json = JSONObject(previous.content) + val patch = JSONObject(change) + patch.keys().forEach { json.put(it, patch.get(it)) } + assertFalse(change, canUpdateIdentitySubtitle(previous, NativeListItem.parse(json))) + } + } +} diff --git a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt new file mode 100644 index 00000000..b7e17125 --- /dev/null +++ b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt @@ -0,0 +1,22 @@ +package com.margelo.nitro.nativelist + +import org.robolectric.annotation.Implementation +import org.robolectric.annotation.Implements +import java.nio.ByteBuffer + +// PNG lifecycle tests do not load the Android-only AVIF JNI library on the JVM. +@Implements(className = "org.aomedia.avif.android.AvifDecoder", isInAndroidSdk = false) +class PngOnlyAvifDecoder { + companion object { + @JvmStatic + @Implementation + fun __staticInitializer__() = Unit + + @JvmStatic + @Implementation + fun isAvifImage(data: ByteBuffer): Boolean { + check(data.limit() >= 4 && data.getInt(0) == 0x89504E47.toInt()) { "Only PNG fixtures are supported" } + return false + } + } +} From c98bec336278f8a47d3ce113a3e67b92beaf735b Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 10 Sep 2026 10:34:47 +0800 Subject: [PATCH 2/3] chore: bump native packages to 3.0.115-alpha.0 --- native-modules/native-logger/package.json | 5 +++-- native-modules/react-native-aes-crypto/package.json | 5 +++-- native-modules/react-native-app-update/package.json | 5 +++-- native-modules/react-native-async-storage/package.json | 5 +++-- native-modules/react-native-background-thread/package.json | 5 +++-- native-modules/react-native-bundle-crypto/package.json | 5 +++-- native-modules/react-native-bundle-update/package.json | 5 +++-- .../react-native-check-biometric-auth-changed/package.json | 5 +++-- native-modules/react-native-cloud-fs/package.json | 5 +++-- native-modules/react-native-cloud-kit-module/package.json | 5 +++-- native-modules/react-native-device-utils/package.json | 5 +++-- native-modules/react-native-dns-lookup/package.json | 5 +++-- native-modules/react-native-get-random-values/package.json | 5 +++-- native-modules/react-native-keychain-module/package.json | 5 +++-- native-modules/react-native-lite-card/package.json | 5 +++-- native-modules/react-native-network-info/package.json | 5 +++-- native-modules/react-native-network-throttle/package.json | 5 +++-- native-modules/react-native-pbkdf2/package.json | 5 +++-- native-modules/react-native-perf-memory/package.json | 5 +++-- native-modules/react-native-perf-stats/package.json | 5 +++-- native-modules/react-native-ping/package.json | 5 +++-- native-modules/react-native-range-downloader/package.json | 5 +++-- native-modules/react-native-sni-connect/package.json | 5 +++-- native-modules/react-native-splash-screen/package.json | 5 +++-- .../react-native-split-bundle-loader/package.json | 5 +++-- native-modules/react-native-tcp-socket/package.json | 5 +++-- native-modules/react-native-zip-archive/package.json | 5 +++-- native-views/react-native-auto-size-input/package.json | 5 +++-- native-views/react-native-chart-webview/package.json | 5 +++-- native-views/react-native-image/package.json | 7 ++++--- native-views/react-native-native-list/package.json | 7 ++++--- native-views/react-native-pager-view/package.json | 5 +++-- native-views/react-native-perp-depth-bar/package.json | 5 +++-- native-views/react-native-scroll-guard/package.json | 5 +++-- native-views/react-native-segment-slider/package.json | 5 +++-- native-views/react-native-skeleton/package.json | 5 +++-- native-views/react-native-tab-view/package.json | 5 +++-- native-views/react-native-text-input/package.json | 5 +++-- native-views/react-native-text/package.json | 5 +++-- yarn.lock | 4 ++-- 40 files changed, 121 insertions(+), 82 deletions(-) diff --git a/native-modules/native-logger/package.json b/native-modules/native-logger/package.json index b2ec4e83..f14e4171 100644 --- a/native-modules/native-logger/package.json +++ b/native-modules/native-logger/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-native-logger", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-native-logger", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-aes-crypto/package.json b/native-modules/react-native-aes-crypto/package.json index bd03602b..4d15f349 100644 --- a/native-modules/react-native-aes-crypto/package.json +++ b/native-modules/react-native-aes-crypto/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-aes-crypto", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-aes-crypto", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -158,5 +158,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-app-update/package.json b/native-modules/react-native-app-update/package.json index b5f8bc26..e9d4fec7 100644 --- a/native-modules/react-native-app-update/package.json +++ b/native-modules/react-native-app-update/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-app-update", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-app-update", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-async-storage/package.json b/native-modules/react-native-async-storage/package.json index a916f567..861b9f20 100644 --- a/native-modules/react-native-async-storage/package.json +++ b/native-modules/react-native-async-storage/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-async-storage", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-async-storage", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -164,5 +164,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-background-thread/package.json b/native-modules/react-native-background-thread/package.json index 6f37ecd7..8732ca50 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-background-thread", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -167,5 +167,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-bundle-crypto/package.json b/native-modules/react-native-bundle-crypto/package.json index 594d30f1..4d8cca7c 100644 --- a/native-modules/react-native-bundle-crypto/package.json +++ b/native-modules/react-native-bundle-crypto/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-bundle-crypto", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-bundle-crypto", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,5 +165,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-bundle-update/package.json b/native-modules/react-native-bundle-update/package.json index 2e50ecfb..168bdb81 100644 --- a/native-modules/react-native-bundle-update/package.json +++ b/native-modules/react-native-bundle-update/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-bundle-update", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-bundle-update", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } 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 7ad2ebff..80553700 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-check-biometric-auth-changed", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-cloud-fs/package.json b/native-modules/react-native-cloud-fs/package.json index b6a04d8e..989daa0b 100644 --- a/native-modules/react-native-cloud-fs/package.json +++ b/native-modules/react-native-cloud-fs/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-cloud-fs", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-cloud-fs TurboModule for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -89,5 +89,6 @@ "RNCloudFs": "CloudFs" } } - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-cloud-kit-module/package.json b/native-modules/react-native-cloud-kit-module/package.json index 9f2bb3f6..88cc7003 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-cloud-kit-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-device-utils/package.json b/native-modules/react-native-device-utils/package.json index 81d7022f..5df5311f 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-device-utils", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-dns-lookup/package.json b/native-modules/react-native-dns-lookup/package.json index c90453f6..1d20bb3c 100644 --- a/native-modules/react-native-dns-lookup/package.json +++ b/native-modules/react-native-dns-lookup/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-dns-lookup", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-dns-lookup", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -164,5 +164,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-get-random-values/package.json b/native-modules/react-native-get-random-values/package.json index 229d3517..f8a4d657 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-get-random-values", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-keychain-module/package.json b/native-modules/react-native-keychain-module/package.json index fd5fb973..0f100b43 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-keychain-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-lite-card/package.json b/native-modules/react-native-lite-card/package.json index eaf63974..27b3c1f9 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "lite card", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -168,5 +168,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-network-info/package.json b/native-modules/react-native-network-info/package.json index 0db4739f..aeba09db 100644 --- a/native-modules/react-native-network-info/package.json +++ b/native-modules/react-native-network-info/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-network-info", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-network-info", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -164,5 +164,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-network-throttle/package.json b/native-modules/react-native-network-throttle/package.json index 60d1ac12..d1aad441 100644 --- a/native-modules/react-native-network-throttle/package.json +++ b/native-modules/react-native-network-throttle/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-network-throttle", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-network-throttle", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -142,5 +142,6 @@ } } } - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-pbkdf2/package.json b/native-modules/react-native-pbkdf2/package.json index dc78bb31..917c9bfe 100644 --- a/native-modules/react-native-pbkdf2/package.json +++ b/native-modules/react-native-pbkdf2/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-pbkdf2", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-pbkdf2", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -158,5 +158,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-perf-memory/package.json b/native-modules/react-native-perf-memory/package.json index 5cc16cee..0c0927da 100644 --- a/native-modules/react-native-perf-memory/package.json +++ b/native-modules/react-native-perf-memory/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-perf-memory", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-perf-memory", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-perf-stats/package.json b/native-modules/react-native-perf-stats/package.json index d9a94f66..dabda0ed 100644 --- a/native-modules/react-native-perf-stats/package.json +++ b/native-modules/react-native-perf-stats/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-perf-stats", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-perf-stats", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,5 +165,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-ping/package.json b/native-modules/react-native-ping/package.json index d1a895ea..02563ef7 100644 --- a/native-modules/react-native-ping/package.json +++ b/native-modules/react-native-ping/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-ping", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-ping TurboModule for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -89,5 +89,6 @@ "RNReactNativePing": "Ping" } } - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-range-downloader/package.json b/native-modules/react-native-range-downloader/package.json index 366e3222..ef1173da 100644 --- a/native-modules/react-native-range-downloader/package.json +++ b/native-modules/react-native-range-downloader/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-range-downloader", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-range-downloader", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,5 +165,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-sni-connect/package.json b/native-modules/react-native-sni-connect/package.json index 68ccaa26..59ca6432 100644 --- a/native-modules/react-native-sni-connect/package.json +++ b/native-modules/react-native-sni-connect/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-sni-connect", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "A React Native library for SNI-based HTTP requests with DNS caching and request management", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -161,5 +161,6 @@ "languages": "kotlin-objc", "type": "turbo-module", "version": "0.54.8" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-splash-screen/package.json b/native-modules/react-native-splash-screen/package.json index fe3f1471..e2505f9d 100644 --- a/native-modules/react-native-splash-screen/package.json +++ b/native-modules/react-native-splash-screen/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-splash-screen", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-splash-screen", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-split-bundle-loader/package.json b/native-modules/react-native-split-bundle-loader/package.json index 98daa208..c5441217 100644 --- a/native-modules/react-native-split-bundle-loader/package.json +++ b/native-modules/react-native-split-bundle-loader/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-split-bundle-loader", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-split-bundle-loader", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,5 +165,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-tcp-socket/package.json b/native-modules/react-native-tcp-socket/package.json index cb85ab75..7dc1ea6a 100644 --- a/native-modules/react-native-tcp-socket/package.json +++ b/native-modules/react-native-tcp-socket/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-tcp-socket", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-tcp-socket", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -159,5 +159,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-modules/react-native-zip-archive/package.json b/native-modules/react-native-zip-archive/package.json index eddcb9e4..b972089a 100644 --- a/native-modules/react-native-zip-archive/package.json +++ b/native-modules/react-native-zip-archive/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-zip-archive", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-zip-archive Nitro HybridObject for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -94,5 +94,6 @@ } ] ] - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-auto-size-input/package.json b/native-views/react-native-auto-size-input/package.json index d73e121d..237e89cd 100644 --- a/native-views/react-native-auto-size-input/package.json +++ b/native-views/react-native-auto-size-input/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-auto-size-input", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "Auto-sizing text input with font scaling, prefix and suffix support", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -167,5 +167,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-chart-webview/package.json b/native-views/react-native-chart-webview/package.json index ace62eef..9248e50d 100644 --- a/native-views/react-native-chart-webview/package.json +++ b/native-views/react-native-chart-webview/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-chart-webview", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-chart-webview", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-image/package.json b/native-views/react-native-image/package.json index 8e4062c7..5d658bf3 100644 --- a/native-views/react-native-image/package.json +++ b/native-views/react-native-image/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-image", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "High-performance native image view for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -81,7 +81,7 @@ "typescript": "^5.9.2" }, "peerDependencies": { - "@onekeyfe/react-native-skeleton": "3.0.114", + "@onekeyfe/react-native-skeleton": "3.0.115-alpha.0", "react": "*", "react-native": "*", "react-native-nitro-modules": "0.37.0" @@ -124,5 +124,6 @@ "modulePathIgnorePatterns": [ "/lib/" ] - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-native-list/package.json b/native-views/react-native-native-list/package.json index 860924e6..40a396ea 100644 --- a/native-views/react-native-native-list/package.json +++ b/native-views/react-native-native-list/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-native-list", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "Template-driven native RecyclerView and UICollectionView for React Native", "source": "./src/index.ts", "main": "./lib/module/index.js", @@ -82,7 +82,7 @@ "typescript": "^5.9.2" }, "peerDependencies": { - "@onekeyfe/react-native-image": "3.0.114", + "@onekeyfe/react-native-image": "3.0.115-alpha.0", "react": "*", "react-native": "*", "react-native-nitro-modules": "0.37.0" @@ -122,5 +122,6 @@ "singleQuote": true, "tabWidth": 2, "trailingComma": "es5" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-pager-view/package.json b/native-views/react-native-pager-view/package.json index c416a79c..2bbc78f2 100644 --- a/native-views/react-native-pager-view/package.json +++ b/native-views/react-native-pager-view/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-pager-view", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "React Native wrapper for Android and iOS ViewPager", "source": "./src/index.tsx", "main": "./lib/module/index.js", @@ -98,5 +98,6 @@ "RNCViewPager": "RNCPagerViewComponentView" } } - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-perp-depth-bar/package.json b/native-views/react-native-perp-depth-bar/package.json index e59d5777..6699f465 100644 --- a/native-views/react-native-perp-depth-bar/package.json +++ b/native-views/react-native-perp-depth-bar/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-perp-depth-bar", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-perp-depth-bar", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-scroll-guard/package.json b/native-views/react-native-scroll-guard/package.json index ae273c2c..8d738eb8 100644 --- a/native-views/react-native-scroll-guard/package.json +++ b/native-views/react-native-scroll-guard/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-scroll-guard", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "A native view wrapper that prevents parent scrollable containers (PagerView/ViewPager2) from intercepting child scroll gestures", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -103,5 +103,6 @@ "create-react-native-library": { "type": "nitro-view", "languages": "kotlin-swift" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-segment-slider/package.json b/native-views/react-native-segment-slider/package.json index dec129c1..ebf323a5 100644 --- a/native-views/react-native-segment-slider/package.json +++ b/native-views/react-native-segment-slider/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-segment-slider", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-segment-slider", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,5 +166,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-skeleton/package.json b/native-views/react-native-skeleton/package.json index 29812dc0..a45f3aee 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": "3.0.114", + "version": "3.0.115-alpha.0", "description": "react-native-skeleton", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -167,5 +167,6 @@ "release-it" ], "version": "0.56.0" - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-tab-view/package.json b/native-views/react-native-tab-view/package.json index 548ec07b..1353b269 100644 --- a/native-views/react-native-tab-view/package.json +++ b/native-views/react-native-tab-view/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-tab-view", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "Native Bottom Tabs for React Native (UIKit implementation)", "source": "./src/index.tsx", "main": "./lib/module/index.js", @@ -111,5 +111,6 @@ ] } } - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-text-input/package.json b/native-views/react-native-text-input/package.json index 7db8067e..8c8ae2ab 100644 --- a/native-views/react-native-text-input/package.json +++ b/native-views/react-native-text-input/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-text-input", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "React Native TextInput with native paste events", "source": "./src/index.tsx", "main": "./lib/module/index.js", @@ -89,5 +89,6 @@ "android": { "javaPackageName": "com.textinput" } - } + }, + "stableVersion": "3.0.114" } diff --git a/native-views/react-native-text/package.json b/native-views/react-native-text/package.json index a5b4f5df..c1791bb3 100644 --- a/native-views/react-native-text/package.json +++ b/native-views/react-native-text/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-text", - "version": "3.0.114", + "version": "3.0.115-alpha.0", "description": "Opt-in native text rendering for React Native", "source": "./src/index.ts", "main": "./lib/module/index.js", @@ -114,5 +114,6 @@ "android": { "javaPackageName": "com.onekey.text" } - } + }, + "stableVersion": "3.0.114" } diff --git a/yarn.lock b/yarn.lock index 57caaa1c..969867c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3491,7 +3491,7 @@ __metadata: react-test-renderer: "npm:19.2.3" typescript: "npm:^5.9.2" peerDependencies: - "@onekeyfe/react-native-skeleton": 3.0.114 + "@onekeyfe/react-native-skeleton": 3.0.115-alpha.0 react: "*" react-native: "*" react-native-nitro-modules: 0.37.0 @@ -3591,7 +3591,7 @@ __metadata: react-native-nitro-modules: "npm:0.37.0" typescript: "npm:^5.9.2" peerDependencies: - "@onekeyfe/react-native-image": 3.0.114 + "@onekeyfe/react-native-image": 3.0.115-alpha.0 react: "*" react-native: "*" react-native-nitro-modules: 0.37.0 From 226c3a358e424d710e395cd4b80d176d9e9b2217 Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 10 Sep 2026 11:33:49 +0800 Subject: [PATCH 3/3] chore: remove native release and test build changes --- native-modules/native-logger/package.json | 5 +- .../react-native-aes-crypto/package.json | 5 +- .../react-native-app-update/package.json | 5 +- .../react-native-async-storage/package.json | 5 +- .../package.json | 5 +- .../react-native-bundle-crypto/package.json | 5 +- .../react-native-bundle-update/package.json | 5 +- .../package.json | 5 +- .../react-native-cloud-fs/package.json | 5 +- .../package.json | 5 +- .../react-native-device-utils/package.json | 5 +- .../react-native-dns-lookup/package.json | 5 +- .../package.json | 5 +- .../react-native-keychain-module/package.json | 5 +- .../react-native-lite-card/package.json | 5 +- .../react-native-network-info/package.json | 5 +- .../package.json | 5 +- .../react-native-pbkdf2/package.json | 5 +- .../react-native-perf-memory/package.json | 5 +- .../react-native-perf-stats/package.json | 5 +- native-modules/react-native-ping/package.json | 5 +- .../package.json | 5 +- .../react-native-sni-connect/package.json | 5 +- .../react-native-splash-screen/package.json | 5 +- .../package.json | 5 +- .../react-native-tcp-socket/package.json | 5 +- .../react-native-zip-archive/package.json | 5 +- .../react-native-auto-size-input/package.json | 5 +- .../react-native-chart-webview/package.json | 5 +- .../react-native-image/android/build.gradle | 2 - .../OneKeyBlockieAvatarLoaderTest.kt | 5 - .../onekeyimage/OneKeyImageLifecycleTest.kt | 136 ------------------ .../nitro/onekeyimage/PngOnlyAvifDecoder.kt | 22 --- native-views/react-native-image/package.json | 7 +- .../android/build.gradle | 3 - .../nativelist/NativeListRowBindingTest.kt | 128 ----------------- .../nativelist/NativeListRowUpdatesTest.kt | 53 ------- .../onekey/nativelist/PngOnlyAvifDecoder.kt | 22 --- .../react-native-native-list/package.json | 7 +- .../react-native-pager-view/package.json | 5 +- .../react-native-perp-depth-bar/package.json | 5 +- .../react-native-scroll-guard/package.json | 5 +- .../react-native-segment-slider/package.json | 5 +- .../react-native-skeleton/package.json | 5 +- .../react-native-tab-view/package.json | 5 +- .../react-native-text-input/package.json | 5 +- native-views/react-native-text/package.json | 5 +- yarn.lock | 4 +- 48 files changed, 82 insertions(+), 492 deletions(-) delete mode 100644 native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt delete mode 100644 native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt delete mode 100644 native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt delete mode 100644 native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt delete mode 100644 native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt diff --git a/native-modules/native-logger/package.json b/native-modules/native-logger/package.json index f14e4171..b2ec4e83 100644 --- a/native-modules/native-logger/package.json +++ b/native-modules/native-logger/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-native-logger", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-native-logger", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-aes-crypto/package.json b/native-modules/react-native-aes-crypto/package.json index 4d15f349..bd03602b 100644 --- a/native-modules/react-native-aes-crypto/package.json +++ b/native-modules/react-native-aes-crypto/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-aes-crypto", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-aes-crypto", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -158,6 +158,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-app-update/package.json b/native-modules/react-native-app-update/package.json index e9d4fec7..b5f8bc26 100644 --- a/native-modules/react-native-app-update/package.json +++ b/native-modules/react-native-app-update/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-app-update", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-app-update", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-async-storage/package.json b/native-modules/react-native-async-storage/package.json index 861b9f20..a916f567 100644 --- a/native-modules/react-native-async-storage/package.json +++ b/native-modules/react-native-async-storage/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-async-storage", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-async-storage", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -164,6 +164,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-background-thread/package.json b/native-modules/react-native-background-thread/package.json index 8732ca50..6f37ecd7 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-background-thread", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -167,6 +167,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-bundle-crypto/package.json b/native-modules/react-native-bundle-crypto/package.json index 4d8cca7c..594d30f1 100644 --- a/native-modules/react-native-bundle-crypto/package.json +++ b/native-modules/react-native-bundle-crypto/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-bundle-crypto", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-bundle-crypto", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,6 +165,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-bundle-update/package.json b/native-modules/react-native-bundle-update/package.json index 168bdb81..2e50ecfb 100644 --- a/native-modules/react-native-bundle-update/package.json +++ b/native-modules/react-native-bundle-update/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-bundle-update", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-bundle-update", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } 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 80553700..7ad2ebff 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-check-biometric-auth-changed", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-cloud-fs/package.json b/native-modules/react-native-cloud-fs/package.json index 989daa0b..b6a04d8e 100644 --- a/native-modules/react-native-cloud-fs/package.json +++ b/native-modules/react-native-cloud-fs/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-cloud-fs", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-cloud-fs TurboModule for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -89,6 +89,5 @@ "RNCloudFs": "CloudFs" } } - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-cloud-kit-module/package.json b/native-modules/react-native-cloud-kit-module/package.json index 88cc7003..9f2bb3f6 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-cloud-kit-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-device-utils/package.json b/native-modules/react-native-device-utils/package.json index 5df5311f..81d7022f 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-device-utils", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-dns-lookup/package.json b/native-modules/react-native-dns-lookup/package.json index 1d20bb3c..c90453f6 100644 --- a/native-modules/react-native-dns-lookup/package.json +++ b/native-modules/react-native-dns-lookup/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-dns-lookup", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-dns-lookup", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -164,6 +164,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-get-random-values/package.json b/native-modules/react-native-get-random-values/package.json index f8a4d657..229d3517 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-get-random-values", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-keychain-module/package.json b/native-modules/react-native-keychain-module/package.json index 0f100b43..fd5fb973 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-keychain-module", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-lite-card/package.json b/native-modules/react-native-lite-card/package.json index 27b3c1f9..eaf63974 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "lite card", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -168,6 +168,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-network-info/package.json b/native-modules/react-native-network-info/package.json index aeba09db..0db4739f 100644 --- a/native-modules/react-native-network-info/package.json +++ b/native-modules/react-native-network-info/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-network-info", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-network-info", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -164,6 +164,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-network-throttle/package.json b/native-modules/react-native-network-throttle/package.json index d1aad441..60d1ac12 100644 --- a/native-modules/react-native-network-throttle/package.json +++ b/native-modules/react-native-network-throttle/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-network-throttle", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-network-throttle", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -142,6 +142,5 @@ } } } - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-pbkdf2/package.json b/native-modules/react-native-pbkdf2/package.json index 917c9bfe..dc78bb31 100644 --- a/native-modules/react-native-pbkdf2/package.json +++ b/native-modules/react-native-pbkdf2/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-pbkdf2", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-pbkdf2", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -158,6 +158,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-perf-memory/package.json b/native-modules/react-native-perf-memory/package.json index 0c0927da..5cc16cee 100644 --- a/native-modules/react-native-perf-memory/package.json +++ b/native-modules/react-native-perf-memory/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-perf-memory", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-perf-memory", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-perf-stats/package.json b/native-modules/react-native-perf-stats/package.json index dabda0ed..d9a94f66 100644 --- a/native-modules/react-native-perf-stats/package.json +++ b/native-modules/react-native-perf-stats/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-perf-stats", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-perf-stats", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,6 +165,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-ping/package.json b/native-modules/react-native-ping/package.json index 02563ef7..d1a895ea 100644 --- a/native-modules/react-native-ping/package.json +++ b/native-modules/react-native-ping/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-ping", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-ping TurboModule for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -89,6 +89,5 @@ "RNReactNativePing": "Ping" } } - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-range-downloader/package.json b/native-modules/react-native-range-downloader/package.json index ef1173da..366e3222 100644 --- a/native-modules/react-native-range-downloader/package.json +++ b/native-modules/react-native-range-downloader/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-range-downloader", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-range-downloader", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,6 +165,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-sni-connect/package.json b/native-modules/react-native-sni-connect/package.json index 59ca6432..68ccaa26 100644 --- a/native-modules/react-native-sni-connect/package.json +++ b/native-modules/react-native-sni-connect/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-sni-connect", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "A React Native library for SNI-based HTTP requests with DNS caching and request management", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -161,6 +161,5 @@ "languages": "kotlin-objc", "type": "turbo-module", "version": "0.54.8" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-splash-screen/package.json b/native-modules/react-native-splash-screen/package.json index e2505f9d..fe3f1471 100644 --- a/native-modules/react-native-splash-screen/package.json +++ b/native-modules/react-native-splash-screen/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-splash-screen", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-splash-screen", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-split-bundle-loader/package.json b/native-modules/react-native-split-bundle-loader/package.json index c5441217..98daa208 100644 --- a/native-modules/react-native-split-bundle-loader/package.json +++ b/native-modules/react-native-split-bundle-loader/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-split-bundle-loader", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-split-bundle-loader", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -165,6 +165,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-tcp-socket/package.json b/native-modules/react-native-tcp-socket/package.json index 7dc1ea6a..cb85ab75 100644 --- a/native-modules/react-native-tcp-socket/package.json +++ b/native-modules/react-native-tcp-socket/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-tcp-socket", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-tcp-socket", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -159,6 +159,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-modules/react-native-zip-archive/package.json b/native-modules/react-native-zip-archive/package.json index b972089a..eddcb9e4 100644 --- a/native-modules/react-native-zip-archive/package.json +++ b/native-modules/react-native-zip-archive/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-zip-archive", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-zip-archive Nitro HybridObject for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -94,6 +94,5 @@ } ] ] - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-auto-size-input/package.json b/native-views/react-native-auto-size-input/package.json index 237e89cd..d73e121d 100644 --- a/native-views/react-native-auto-size-input/package.json +++ b/native-views/react-native-auto-size-input/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-auto-size-input", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "Auto-sizing text input with font scaling, prefix and suffix support", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -167,6 +167,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-chart-webview/package.json b/native-views/react-native-chart-webview/package.json index 9248e50d..ace62eef 100644 --- a/native-views/react-native-chart-webview/package.json +++ b/native-views/react-native-chart-webview/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-chart-webview", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-chart-webview", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-image/android/build.gradle b/native-views/react-native-image/android/build.gradle index 852dec71..f6bed366 100644 --- a/native-views/react-native-image/android/build.gradle +++ b/native-views/react-native-image/android/build.gradle @@ -64,7 +64,6 @@ android { sourceSets { main { java.srcDirs += ["generated/java", "generated/jni"] } } - testOptions { unitTests.includeAndroidResources = true } } repositories { mavenCentral(); google() } @@ -83,5 +82,4 @@ dependencies { implementation project(":react-native-nitro-modules") implementation project(":onekeyfe_react-native-skeleton") testImplementation "junit:junit:4.13.2" - testImplementation "org.robolectric:robolectric:4.16.1" } diff --git a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt index 17e00c23..64d5c04a 100644 --- a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt +++ b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyBlockieAvatarLoaderTest.kt @@ -16,9 +16,6 @@ import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import java.io.IOException import java.io.File import java.nio.file.Files @@ -29,8 +26,6 @@ import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicInteger -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [35]) class OneKeyBlockieAvatarLoaderTest { private val uri = "onekey-avatar://blockie/v1/0x1234" diff --git a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt deleted file mode 100644 index f53796bf..00000000 --- a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/OneKeyImageLifecycleTest.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.margelo.nitro.onekeyimage - -import android.app.Activity -import android.graphics.Bitmap -import android.graphics.Color -import android.os.Looper -import android.widget.FrameLayout -import android.widget.ImageView -import com.bumptech.glide.request.target.Target -import com.facebook.react.bridge.BridgeReactContext -import com.facebook.react.uimanager.ThemedReactContext -import org.junit.After -import org.junit.Assert.* -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.Robolectric -import org.robolectric.RobolectricTestRunner -import org.robolectric.Shadows.shadowOf -import org.robolectric.annotation.Config -import java.io.File - -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [35], shadows = [PngOnlyAvifDecoder::class]) -class OneKeyImageLifecycleTest { - private val controller = Robolectric.buildActivity(Activity::class.java) - private lateinit var container: FrameLayout - private lateinit var image: HybridOneKeyImage - private lateinit var source: File - - @Before - fun setUp() { - val activity = controller.setup().visible().get() - container = FrameLayout(activity) - activity.setContentView(container) - val context = ThemedReactContext(BridgeReactContext(activity.application), activity, "test", 1) - image = HybridOneKeyImage(context) - source = File.createTempFile("image-lifecycle", ".png", activity.cacheDir) - val bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888).apply { eraseColor(Color.GREEN) } - source.outputStream().use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) } - bitmap.recycle() - container.addView(image.view, FrameLayout.LayoutParams(32, 32)) - image.view.layout(0, 0, 32, 32) - } - - @After - fun tearDown() { - image.dispose() - controller.pause().stop().destroy() - source.delete() - } - - private fun loadImage() { - image.sourceUri = source.toURI().toString() - val deadline = System.nanoTime() + 10_000_000_000L - while ((image.view as ImageView).drawable == null && System.nanoTime() < deadline) { - shadowOf(Looper.getMainLooper()).idle() - Thread.sleep(10) - } - assertNotNull("The local image must finish decoding", (image.view as ImageView).drawable) - } - - private fun target(): Target<*>? = - HybridOneKeyImage::class.java.getDeclaredField("currentTarget").run { - isAccessible = true - get(image) as? Target<*> - } - - @Test - fun droppedImageRetainsItsGlideResourceUntilRemovalTransitionEnds() { - loadImage() - val drawable = (image.view as ImageView).drawable - val request = target()!!.request!! - container.startViewTransition(image.view) - container.removeView(image.view) - assertTrue(image.view.isAttachedToWindow) - - image.onDropView() - - assertSame(drawable, (image.view as ImageView).drawable) - assertFalse("Glide must still own the bitmap while it is drawn", request.isCleared) - container.endViewTransition(image.view) - assertFalse(image.view.isAttachedToWindow) - assertNull((image.view as ImageView).drawable) - assertTrue(request.isCleared) - assertNull(target()) - } - - @Test - fun detachedDropAndExplicitNativeOwnerDisposalReleaseImmediately() { - loadImage() - val request = target()!!.request!! - container.removeView(image.view) - image.onDropView() - assertTrue(request.isCleared) - assertNull((image.view as ImageView).drawable) - - image.prepareForRecycle() - image.usesApplicationRequestManager = true - container.addView(image.view, FrameLayout.LayoutParams(32, 32)) - image.view.layout(0, 0, 32, 32) - loadImage() - val nativeRequest = target()!!.request!! - image.onDropView() - assertTrue(nativeRequest.isCleared) - assertNull((image.view as ImageView).drawable) - } - - @Test - fun dropCancelsPendingLoadsAndRecyclingAllowsANewSource() { - var callbacks = 0 - image.onLoadStart = { callbacks++ } - image.onLoad = { _, _, _ -> callbacks++ } - image.onDisplay = { callbacks++ } - image.sourceUri = source.toURI().toString() - image.onDropView() - shadowOf(Looper.getMainLooper()).idle() - assertEquals(0, callbacks) - assertNull(target()) - - image.prepareForRecycle() - image.onLoad = { _, _, _ -> callbacks++ } - loadImage() - assertEquals(1, callbacks) - } - - @Test - fun sourceOrRecyclingKeyChangesStillClearThePreviousImageImmediately() { - loadImage() - image.recyclingKey = "another-account" - assertNull((image.view as ImageView).drawable) - loadImage() - image.sourceUri = null - assertNull((image.view as ImageView).drawable) - } -} diff --git a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt b/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt deleted file mode 100644 index ec75299c..00000000 --- a/native-views/react-native-image/android/src/test/java/com/margelo/nitro/onekeyimage/PngOnlyAvifDecoder.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.margelo.nitro.onekeyimage - -import org.robolectric.annotation.Implementation -import org.robolectric.annotation.Implements -import java.nio.ByteBuffer - -// PNG lifecycle tests do not load the Android-only AVIF JNI library on the JVM. -@Implements(className = "org.aomedia.avif.android.AvifDecoder", isInAndroidSdk = false) -class PngOnlyAvifDecoder { - companion object { - @JvmStatic - @Implementation - fun __staticInitializer__() = Unit - - @JvmStatic - @Implementation - fun isAvifImage(data: ByteBuffer): Boolean { - check(data.limit() >= 4 && data.getInt(0) == 0x89504E47.toInt()) { "Only PNG fixtures are supported" } - return false - } - } -} diff --git a/native-views/react-native-image/package.json b/native-views/react-native-image/package.json index 5d658bf3..8e4062c7 100644 --- a/native-views/react-native-image/package.json +++ b/native-views/react-native-image/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-image", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "High-performance native image view for OneKey", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -81,7 +81,7 @@ "typescript": "^5.9.2" }, "peerDependencies": { - "@onekeyfe/react-native-skeleton": "3.0.115-alpha.0", + "@onekeyfe/react-native-skeleton": "3.0.114", "react": "*", "react-native": "*", "react-native-nitro-modules": "0.37.0" @@ -124,6 +124,5 @@ "modulePathIgnorePatterns": [ "/lib/" ] - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-native-list/android/build.gradle b/native-views/react-native-native-list/android/build.gradle index ca95d600..a4796fa0 100644 --- a/native-views/react-native-native-list/android/build.gradle +++ b/native-views/react-native-native-list/android/build.gradle @@ -64,7 +64,6 @@ android { buildConfig true prefab true } - testOptions { unitTests.includeAndroidResources = true } buildTypes { release { @@ -103,6 +102,4 @@ dependencies { implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation project(":react-native-nitro-modules") implementation project(":onekeyfe_react-native-image") - testImplementation "junit:junit:4.13.2" - testImplementation "org.robolectric:robolectric:4.16.1" } diff --git a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt deleted file mode 100644 index ff68e41b..00000000 --- a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowBindingTest.kt +++ /dev/null @@ -1,128 +0,0 @@ -package com.margelo.nitro.nativelist - -import android.app.Activity -import android.os.Looper -import android.view.View -import android.view.ViewGroup -import android.widget.FrameLayout -import android.widget.ImageView -import android.widget.TextView -import com.facebook.react.bridge.BridgeReactContext -import com.facebook.react.uimanager.ThemedReactContext -import com.margelo.nitro.onekeyimage.OneKeyImageReusableView -import org.json.JSONObject -import org.junit.After -import org.junit.Assert.* -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.Robolectric -import org.robolectric.RobolectricTestRunner -import org.robolectric.Shadows.shadowOf -import org.robolectric.annotation.Config - -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [35], shadows = [PngOnlyAvifDecoder::class]) -class NativeListRowBindingTest { - private val controller = Robolectric.buildActivity(Activity::class.java) - private lateinit var row: NativeListRowView - - @Before - fun setUp() { - val activity = controller.setup().visible().get() - val context = ThemedReactContext(BridgeReactContext(activity.application), activity, "test", 1) - row = NativeListRowView(context) - val container = FrameLayout(activity) - activity.setContentView(container) - container.addView(row, FrameLayout.LayoutParams(400, 64)) - } - - @After - fun tearDown() { - row.dispose() - controller.pause().stop().destroy() - } - - private fun bind(item: NativeListItem, theme: JSONObject? = null) { - row.bind(item, theme, "linear", "vertical", 0, false, { _, _, fallback -> fallback }) - row.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(64, View.MeasureSpec.EXACTLY)) - row.layout(0, 0, 400, 64) - } - - private fun descendants(view: View): List = buildList { - add(view) - if (view is ViewGroup) for (index in 0 until view.childCount) addAll(descendants(view.getChildAt(index))) - } - - private fun avatar(): ImageView { - val reusable = descendants(row).filterIsInstance() - .first { it.visibility == View.VISIBLE } - return reusable.getChildAt(0) as ImageView - } - - private fun awaitAvatar() { - val deadline = System.nanoTime() + 10_000_000_000L - while (avatar().drawable == null && System.nanoTime() < deadline) { - shadowOf(Looper.getMainLooper()).idle() - Thread.sleep(10) - } - assertNotNull("The avatar must finish decoding", avatar().drawable) - } - - @Test - fun repeatedBalancePatchesKeepTheLoadedAvatarAndExistingTextViews() { - val theme = JSONObject("""{"disabledText":"#777777","secondaryText":"#999999"}""") - bind(accountRow(), theme) - awaitAvatar() - val imageView = avatar() - val drawable = imageView.drawable - val subtitle = descendants(row).filterIsInstance().first { it.text.toString() == "--" } - for (value in listOf("12.34", "12.56", "--", "1.25")) { - bind(accountRow(value), theme) - assertSame(imageView, avatar()) - assertSame("No placeholder between balance updates", drawable, imageView.drawable) - assertEquals(value, subtitle.text.toString()) - assertEquals(android.graphics.Color.parseColor(if (value == "--") "#777777" else "#999999"), subtitle.currentTextColor) - assertEquals("Account #1, $value", row.contentDescription) - shadowOf(Looper.getMainLooper()).idle() - assertSame("No asynchronous avatar reload", drawable, imageView.drawable) - } - } - - @Test - fun subtitlePatchWhileTheAvatarIsLoadingKeepsItsCompletionBindingValid() { - bind(accountRow()) - val epoch = row.bindingEpoch - bind(accountRow("12.34")) - assertEquals(epoch, row.bindingEpoch) - awaitAvatar() - assertEquals("Account #1, 12.34", row.contentDescription) - } - - @Test - fun changedAvatarAndRecycledRowCannotKeepStaleImages() { - bind(accountRow()) - awaitAvatar() - val next = JSONObject(accountRow("12.34").content) - next.getJSONObject("leading").getJSONObject("image") - .put("uri", "onekey-avatar://blockie/v1/0x5678") - bind(NativeListItem.parse(next)) - assertNull(avatar().drawable) - awaitAvatar() - row.recycle() - assertNull(avatar().drawable) - bind(NativeListItem.parse(next)) - awaitAvatar() - } - - @Test - fun themeChangesStillPerformFullBinding() { - bind(accountRow()) - val epoch = row.bindingEpoch - bind(accountRow("12.34"), JSONObject("""{"primaryText":"#FFFFFF","secondaryText":"#AAAAAA"}""")) - assertTrue(row.bindingEpoch > epoch) - val title = descendants(row).filterIsInstance().first { it.text.toString() == "Account #1" } - assertEquals(android.graphics.Color.WHITE, title.currentTextColor) - } -} diff --git a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt deleted file mode 100644 index c28c3f39..00000000 --- a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/NativeListRowUpdatesTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.margelo.nitro.nativelist - -import org.json.JSONArray -import org.json.JSONObject -import org.junit.Assert.* -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config - -internal fun accountRow(value: String = "--"): NativeListItem = NativeListItem.parse(JSONObject(""" - {"key":"account-1","type":"identity","presentation":"accountSelector","height":64, - "title":"Account #1","accessibilityLabel":"Account #1, $value", - "leading":{"kind":"account","image":{"uri":"onekey-avatar://blockie/v1/0x1234"}}, - "subtitleSegments":[{"text":"$value","tone":"${if (value == "--") "disabled" else "secondary"}"},{"text":"0x1234","separatorBefore":true}]} -""")) - -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [35]) -class NativeListRowUpdatesTest { - @Test - fun balanceAndRichTextChangesPreserveTheSameSubtitleSlotsWithoutMutatingRows() { - val previous = accountRow() - val next = accountRow("12.34") - next.json.getJSONArray("subtitleSegments").getJSONObject(0) - .put("textSegments", JSONArray("""[{"text":"0.0"},{"text":"4","style":"subscript"}]""")) - val rich = NativeListItem.parse(next.json) - assertTrue(canUpdateIdentitySubtitle(previous, rich)) - assertTrue(canUpdateIdentitySubtitle(rich, accountRow("12.56"))) - assertEquals("--", previous.json.getJSONArray("subtitleSegments").getJSONObject(0).getString("text")) - assertTrue(rich.json.getJSONArray("subtitleSegments").getJSONObject(0).has("textSegments")) - } - - @Test - fun identityImageActionsThemeRelatedFieldsAndUnknownChangesRequireFullBinding() { - val previous = accountRow() - val changes = listOf( - """{"key":"account-2"}""", """{"type":"action"}""", - """{"leading":{"kind":"account","image":{"uri":"different"}}}""", - """{"trailing":[{"kind":"icon","name":"PlusSmallOutline"}]}""", - """{"height":80}""", """{"presentation":"networkSelector"}""", - """{"revision":1}""", """{"disabled":true}""", """{"unknownField":1}""", - """{"subtitleSegments":[]}""", - """{"subtitleSegments":[{"text":"1"},{"text":"address","separatorBefore":false}]}""", - ) - for (change in changes) { - val json = JSONObject(previous.content) - val patch = JSONObject(change) - patch.keys().forEach { json.put(it, patch.get(it)) } - assertFalse(change, canUpdateIdentitySubtitle(previous, NativeListItem.parse(json))) - } - } -} diff --git a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt b/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt deleted file mode 100644 index b7e17125..00000000 --- a/native-views/react-native-native-list/android/src/test/java/com/onekey/nativelist/PngOnlyAvifDecoder.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.margelo.nitro.nativelist - -import org.robolectric.annotation.Implementation -import org.robolectric.annotation.Implements -import java.nio.ByteBuffer - -// PNG lifecycle tests do not load the Android-only AVIF JNI library on the JVM. -@Implements(className = "org.aomedia.avif.android.AvifDecoder", isInAndroidSdk = false) -class PngOnlyAvifDecoder { - companion object { - @JvmStatic - @Implementation - fun __staticInitializer__() = Unit - - @JvmStatic - @Implementation - fun isAvifImage(data: ByteBuffer): Boolean { - check(data.limit() >= 4 && data.getInt(0) == 0x89504E47.toInt()) { "Only PNG fixtures are supported" } - return false - } - } -} diff --git a/native-views/react-native-native-list/package.json b/native-views/react-native-native-list/package.json index 40a396ea..860924e6 100644 --- a/native-views/react-native-native-list/package.json +++ b/native-views/react-native-native-list/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-native-list", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "Template-driven native RecyclerView and UICollectionView for React Native", "source": "./src/index.ts", "main": "./lib/module/index.js", @@ -82,7 +82,7 @@ "typescript": "^5.9.2" }, "peerDependencies": { - "@onekeyfe/react-native-image": "3.0.115-alpha.0", + "@onekeyfe/react-native-image": "3.0.114", "react": "*", "react-native": "*", "react-native-nitro-modules": "0.37.0" @@ -122,6 +122,5 @@ "singleQuote": true, "tabWidth": 2, "trailingComma": "es5" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-pager-view/package.json b/native-views/react-native-pager-view/package.json index 2bbc78f2..c416a79c 100644 --- a/native-views/react-native-pager-view/package.json +++ b/native-views/react-native-pager-view/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-pager-view", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "React Native wrapper for Android and iOS ViewPager", "source": "./src/index.tsx", "main": "./lib/module/index.js", @@ -98,6 +98,5 @@ "RNCViewPager": "RNCPagerViewComponentView" } } - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-perp-depth-bar/package.json b/native-views/react-native-perp-depth-bar/package.json index 6699f465..e59d5777 100644 --- a/native-views/react-native-perp-depth-bar/package.json +++ b/native-views/react-native-perp-depth-bar/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-perp-depth-bar", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-perp-depth-bar", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-scroll-guard/package.json b/native-views/react-native-scroll-guard/package.json index 8d738eb8..ae273c2c 100644 --- a/native-views/react-native-scroll-guard/package.json +++ b/native-views/react-native-scroll-guard/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-scroll-guard", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "A native view wrapper that prevents parent scrollable containers (PagerView/ViewPager2) from intercepting child scroll gestures", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -103,6 +103,5 @@ "create-react-native-library": { "type": "nitro-view", "languages": "kotlin-swift" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-segment-slider/package.json b/native-views/react-native-segment-slider/package.json index ebf323a5..dec129c1 100644 --- a/native-views/react-native-segment-slider/package.json +++ b/native-views/react-native-segment-slider/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-segment-slider", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-segment-slider", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -166,6 +166,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-skeleton/package.json b/native-views/react-native-skeleton/package.json index a45f3aee..29812dc0 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": "3.0.115-alpha.0", + "version": "3.0.114", "description": "react-native-skeleton", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", @@ -167,6 +167,5 @@ "release-it" ], "version": "0.56.0" - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-tab-view/package.json b/native-views/react-native-tab-view/package.json index 1353b269..548ec07b 100644 --- a/native-views/react-native-tab-view/package.json +++ b/native-views/react-native-tab-view/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-tab-view", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "Native Bottom Tabs for React Native (UIKit implementation)", "source": "./src/index.tsx", "main": "./lib/module/index.js", @@ -111,6 +111,5 @@ ] } } - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-text-input/package.json b/native-views/react-native-text-input/package.json index 8c8ae2ab..7db8067e 100644 --- a/native-views/react-native-text-input/package.json +++ b/native-views/react-native-text-input/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-text-input", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "React Native TextInput with native paste events", "source": "./src/index.tsx", "main": "./lib/module/index.js", @@ -89,6 +89,5 @@ "android": { "javaPackageName": "com.textinput" } - }, - "stableVersion": "3.0.114" + } } diff --git a/native-views/react-native-text/package.json b/native-views/react-native-text/package.json index c1791bb3..a5b4f5df 100644 --- a/native-views/react-native-text/package.json +++ b/native-views/react-native-text/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-text", - "version": "3.0.115-alpha.0", + "version": "3.0.114", "description": "Opt-in native text rendering for React Native", "source": "./src/index.ts", "main": "./lib/module/index.js", @@ -114,6 +114,5 @@ "android": { "javaPackageName": "com.onekey.text" } - }, - "stableVersion": "3.0.114" + } } diff --git a/yarn.lock b/yarn.lock index 969867c6..57caaa1c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3491,7 +3491,7 @@ __metadata: react-test-renderer: "npm:19.2.3" typescript: "npm:^5.9.2" peerDependencies: - "@onekeyfe/react-native-skeleton": 3.0.115-alpha.0 + "@onekeyfe/react-native-skeleton": 3.0.114 react: "*" react-native: "*" react-native-nitro-modules: 0.37.0 @@ -3591,7 +3591,7 @@ __metadata: react-native-nitro-modules: "npm:0.37.0" typescript: "npm:^5.9.2" peerDependencies: - "@onekeyfe/react-native-image": 3.0.115-alpha.0 + "@onekeyfe/react-native-image": 3.0.114 react: "*" react-native: "*" react-native-nitro-modules: 0.37.0