@onekeyfe/react-native-chart-webview 3.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/ChartWebview.podspec +29 -0
  2. package/LICENSE +21 -0
  3. package/README.md +31 -0
  4. package/android/CMakeLists.txt +24 -0
  5. package/android/build.gradle +131 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  8. package/android/src/main/java/com/margelo/nitro/chartwebview/ChartWebview.kt +331 -0
  9. package/android/src/main/java/com/margelo/nitro/chartwebview/ChartWebviewPackage.kt +29 -0
  10. package/android/src/main/java/com/margelo/nitro/chartwebview/PooledChartWebView.kt +385 -0
  11. package/ios/ChartWebview.swift +747 -0
  12. package/lib/module/ChartWebview.nitro.js +4 -0
  13. package/lib/module/ChartWebview.nitro.js.map +1 -0
  14. package/lib/module/bridge.js +30 -0
  15. package/lib/module/bridge.js.map +1 -0
  16. package/lib/module/index.js +19 -0
  17. package/lib/module/index.js.map +1 -0
  18. package/lib/module/package.json +1 -0
  19. package/lib/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
  20. package/lib/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
  21. package/lib/nitrogen/generated/android/c++/JHybridChartWebviewSpec.cpp +186 -0
  22. package/lib/nitrogen/generated/android/c++/JHybridChartWebviewSpec.hpp +88 -0
  23. package/lib/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.cpp +96 -0
  24. package/lib/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.hpp +49 -0
  25. package/lib/nitrogen/generated/android/chartwebview+autolinking.cmake +83 -0
  26. package/lib/nitrogen/generated/android/chartwebview+autolinking.gradle +27 -0
  27. package/lib/nitrogen/generated/android/chartwebviewOnLoad.cpp +50 -0
  28. package/lib/nitrogen/generated/android/chartwebviewOnLoad.hpp +25 -0
  29. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/Func_void.kt +80 -0
  30. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/Func_void_std__string.kt +80 -0
  31. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/HybridChartWebviewSpec.kt +153 -0
  32. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/chartwebviewOnLoad.kt +35 -0
  33. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/views/HybridChartWebviewManager.kt +50 -0
  34. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/views/HybridChartWebviewStateUpdater.kt +23 -0
  35. package/lib/nitrogen/generated/ios/ChartWebview+autolinking.rb +60 -0
  36. package/lib/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Bridge.cpp +49 -0
  37. package/lib/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Bridge.hpp +158 -0
  38. package/lib/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Umbrella.hpp +46 -0
  39. package/lib/nitrogen/generated/ios/ChartWebviewAutolinking.mm +33 -0
  40. package/lib/nitrogen/generated/ios/ChartWebviewAutolinking.swift +25 -0
  41. package/lib/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.cpp +11 -0
  42. package/lib/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.hpp +164 -0
  43. package/lib/nitrogen/generated/ios/c++/views/HybridChartWebviewComponent.mm +146 -0
  44. package/lib/nitrogen/generated/ios/swift/Func_void.swift +47 -0
  45. package/lib/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  46. package/lib/nitrogen/generated/ios/swift/HybridChartWebviewSpec.swift +68 -0
  47. package/lib/nitrogen/generated/ios/swift/HybridChartWebviewSpec_cxx.swift +450 -0
  48. package/lib/nitrogen/generated/shared/c++/HybridChartWebviewSpec.cpp +45 -0
  49. package/lib/nitrogen/generated/shared/c++/HybridChartWebviewSpec.hpp +87 -0
  50. package/lib/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.cpp +207 -0
  51. package/lib/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.hpp +118 -0
  52. package/lib/nitrogen/generated/shared/json/ChartWebviewConfig.json +20 -0
  53. package/lib/nitrogen/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
  54. package/lib/nitrogen/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
  55. package/lib/nitrogen/nitrogen/generated/android/c++/JHybridChartWebviewSpec.cpp +186 -0
  56. package/lib/nitrogen/nitrogen/generated/android/c++/JHybridChartWebviewSpec.hpp +88 -0
  57. package/lib/nitrogen/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.cpp +96 -0
  58. package/lib/nitrogen/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.hpp +49 -0
  59. package/lib/nitrogen/nitrogen/generated/android/chartwebview+autolinking.cmake +83 -0
  60. package/lib/nitrogen/nitrogen/generated/android/chartwebview+autolinking.gradle +27 -0
  61. package/lib/nitrogen/nitrogen/generated/android/chartwebviewOnLoad.cpp +50 -0
  62. package/lib/nitrogen/nitrogen/generated/android/chartwebviewOnLoad.hpp +25 -0
  63. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/Func_void.kt +80 -0
  64. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/Func_void_std__string.kt +80 -0
  65. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/HybridChartWebviewSpec.kt +153 -0
  66. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/chartwebviewOnLoad.kt +35 -0
  67. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/views/HybridChartWebviewManager.kt +50 -0
  68. package/lib/nitrogen/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/views/HybridChartWebviewStateUpdater.kt +23 -0
  69. package/lib/nitrogen/nitrogen/generated/ios/ChartWebview+autolinking.rb +60 -0
  70. package/lib/nitrogen/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Bridge.cpp +49 -0
  71. package/lib/nitrogen/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Bridge.hpp +158 -0
  72. package/lib/nitrogen/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Umbrella.hpp +46 -0
  73. package/lib/nitrogen/nitrogen/generated/ios/ChartWebviewAutolinking.mm +33 -0
  74. package/lib/nitrogen/nitrogen/generated/ios/ChartWebviewAutolinking.swift +25 -0
  75. package/lib/nitrogen/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.cpp +11 -0
  76. package/lib/nitrogen/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.hpp +164 -0
  77. package/lib/nitrogen/nitrogen/generated/ios/c++/views/HybridChartWebviewComponent.mm +146 -0
  78. package/lib/nitrogen/nitrogen/generated/ios/swift/Func_void.swift +47 -0
  79. package/lib/nitrogen/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  80. package/lib/nitrogen/nitrogen/generated/ios/swift/HybridChartWebviewSpec.swift +68 -0
  81. package/lib/nitrogen/nitrogen/generated/ios/swift/HybridChartWebviewSpec_cxx.swift +450 -0
  82. package/lib/nitrogen/nitrogen/generated/shared/c++/HybridChartWebviewSpec.cpp +45 -0
  83. package/lib/nitrogen/nitrogen/generated/shared/c++/HybridChartWebviewSpec.hpp +87 -0
  84. package/lib/nitrogen/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.cpp +207 -0
  85. package/lib/nitrogen/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.hpp +118 -0
  86. package/lib/nitrogen/nitrogen/generated/shared/json/ChartWebviewConfig.json +20 -0
  87. package/lib/typescript/package.json +1 -0
  88. package/lib/typescript/src/ChartWebview.nitro.d.ts +21 -0
  89. package/lib/typescript/src/ChartWebview.nitro.d.ts.map +1 -0
  90. package/lib/typescript/src/bridge.d.ts +2 -0
  91. package/lib/typescript/src/bridge.d.ts.map +1 -0
  92. package/lib/typescript/src/index.d.ts +145 -0
  93. package/lib/typescript/src/index.d.ts.map +1 -0
  94. package/nitro.json +17 -0
  95. package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
  96. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
  97. package/nitrogen/generated/android/c++/JHybridChartWebviewSpec.cpp +186 -0
  98. package/nitrogen/generated/android/c++/JHybridChartWebviewSpec.hpp +88 -0
  99. package/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.cpp +96 -0
  100. package/nitrogen/generated/android/c++/views/JHybridChartWebviewStateUpdater.hpp +49 -0
  101. package/nitrogen/generated/android/chartwebview+autolinking.cmake +83 -0
  102. package/nitrogen/generated/android/chartwebview+autolinking.gradle +27 -0
  103. package/nitrogen/generated/android/chartwebviewOnLoad.cpp +50 -0
  104. package/nitrogen/generated/android/chartwebviewOnLoad.hpp +25 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/Func_void.kt +80 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/Func_void_std__string.kt +80 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/HybridChartWebviewSpec.kt +153 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/chartwebviewOnLoad.kt +35 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/views/HybridChartWebviewManager.kt +50 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/chartwebview/views/HybridChartWebviewStateUpdater.kt +23 -0
  111. package/nitrogen/generated/ios/ChartWebview+autolinking.rb +60 -0
  112. package/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Bridge.cpp +49 -0
  113. package/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Bridge.hpp +158 -0
  114. package/nitrogen/generated/ios/ChartWebview-Swift-Cxx-Umbrella.hpp +46 -0
  115. package/nitrogen/generated/ios/ChartWebviewAutolinking.mm +33 -0
  116. package/nitrogen/generated/ios/ChartWebviewAutolinking.swift +25 -0
  117. package/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.cpp +11 -0
  118. package/nitrogen/generated/ios/c++/HybridChartWebviewSpecSwift.hpp +164 -0
  119. package/nitrogen/generated/ios/c++/views/HybridChartWebviewComponent.mm +146 -0
  120. package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
  121. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  122. package/nitrogen/generated/ios/swift/HybridChartWebviewSpec.swift +68 -0
  123. package/nitrogen/generated/ios/swift/HybridChartWebviewSpec_cxx.swift +450 -0
  124. package/nitrogen/generated/shared/c++/HybridChartWebviewSpec.cpp +45 -0
  125. package/nitrogen/generated/shared/c++/HybridChartWebviewSpec.hpp +87 -0
  126. package/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.cpp +207 -0
  127. package/nitrogen/generated/shared/c++/views/HybridChartWebviewComponent.hpp +118 -0
  128. package/nitrogen/generated/shared/json/ChartWebviewConfig.json +20 -0
  129. package/package.json +170 -0
  130. package/src/ChartWebview.nitro.ts +59 -0
  131. package/src/bridge.ts +27 -0
  132. package/src/index.tsx +20 -0
@@ -0,0 +1,29 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "ChartWebview"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported }
14
+ s.source = { :git => "https://github.com/OneKeyHQ/app-views/react-native-chart-webview.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = [
17
+ "ios/**/*.{swift}",
18
+ "ios/**/*.{m,mm}",
19
+ "cpp/**/*.{hpp,cpp}",
20
+ ]
21
+
22
+ s.dependency 'React-jsi'
23
+ s.dependency 'React-callinvoker'
24
+
25
+ load 'nitrogen/generated/ios/ChartWebview+autolinking.rb'
26
+ add_nitrogen_files(s)
27
+
28
+ install_modules_dependencies(s)
29
+ end
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 OneKey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # @onekeyfe/react-native-chart-webview
2
+
3
+ ChartWebview view for React Native
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ yarn add @onekeyfe/react-native-chart-webview
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```js
14
+ import { ChartWebviewView } from '@onekeyfe/react-native-chart-webview';
15
+
16
+ // ...
17
+
18
+ <ChartWebviewView color="#ff0000" style={{ width: 100, height: 100 }} />
19
+ ```
20
+
21
+ ## Contributing
22
+
23
+ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
24
+
25
+ ## License
26
+
27
+ MIT
28
+
29
+ ---
30
+
31
+ Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
@@ -0,0 +1,24 @@
1
+ project(chartwebview)
2
+ cmake_minimum_required(VERSION 3.9.0)
3
+
4
+ set(PACKAGE_NAME chartwebview)
5
+ set(CMAKE_VERBOSE_MAKEFILE ON)
6
+ set(CMAKE_CXX_STANDARD 20)
7
+
8
+ # Define C++ library and add all sources
9
+ add_library(${PACKAGE_NAME} SHARED src/main/cpp/cpp-adapter.cpp)
10
+
11
+ # Add Nitrogen specs :)
12
+ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/chartwebview+autolinking.cmake)
13
+
14
+ # Set up local includes
15
+ include_directories("src/main/cpp" "../cpp")
16
+
17
+ find_library(LOG_LIB log)
18
+
19
+ # Link all libraries together
20
+ target_link_libraries(
21
+ ${PACKAGE_NAME}
22
+ ${LOG_LIB}
23
+ android # <-- Android core
24
+ )
@@ -0,0 +1,131 @@
1
+ buildscript {
2
+ ext.getExtOrDefault = {name ->
3
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ChartWebview_' + name]
4
+ }
5
+
6
+ repositories {
7
+ google()
8
+ mavenCentral()
9
+ }
10
+
11
+ dependencies {
12
+ classpath "com.android.tools.build:gradle:8.7.2"
13
+ // noinspection DifferentKotlinGradleVersion
14
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
15
+ }
16
+ }
17
+
18
+ def reactNativeArchitectures() {
19
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
20
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
21
+ }
22
+
23
+ apply plugin: "com.android.library"
24
+ apply plugin: "kotlin-android"
25
+ apply from: '../nitrogen/generated/android/chartwebview+autolinking.gradle'
26
+
27
+ apply plugin: "com.facebook.react"
28
+
29
+ def getExtOrIntegerDefault(name) {
30
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["ChartWebview_" + name]).toInteger()
31
+ }
32
+
33
+ android {
34
+ namespace "com.margelo.nitro.chartwebview"
35
+
36
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
37
+
38
+ defaultConfig {
39
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
40
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
41
+
42
+ externalNativeBuild {
43
+ cmake {
44
+ cppFlags "-frtti -fexceptions -Wall -fstack-protector-all"
45
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
46
+ abiFilters (*reactNativeArchitectures())
47
+
48
+ buildTypes {
49
+ debug {
50
+ cppFlags "-O1 -g"
51
+ }
52
+ release {
53
+ cppFlags "-O2"
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ externalNativeBuild {
61
+ cmake {
62
+ path "CMakeLists.txt"
63
+ }
64
+ }
65
+
66
+ packagingOptions {
67
+ excludes = [
68
+ "META-INF",
69
+ "META-INF/**",
70
+ "**/libc++_shared.so",
71
+ "**/libfbjni.so",
72
+ "**/libjsi.so",
73
+ "**/libfolly_json.so",
74
+ "**/libfolly_runtime.so",
75
+ "**/libglog.so",
76
+ "**/libhermes.so",
77
+ "**/libhermes-executor-debug.so",
78
+ "**/libhermes_executor.so",
79
+ "**/libreactnative.so",
80
+ "**/libreactnativejni.so",
81
+ "**/libturbomodulejsijni.so",
82
+ "**/libreact_nativemodule_core.so",
83
+ "**/libjscexecutor.so"
84
+ ]
85
+ }
86
+
87
+ buildFeatures {
88
+ buildConfig true
89
+ prefab true
90
+ }
91
+
92
+ buildTypes {
93
+ release {
94
+ minifyEnabled false
95
+ }
96
+ }
97
+
98
+ lintOptions {
99
+ disable "GradleCompatible"
100
+ }
101
+
102
+ compileOptions {
103
+ sourceCompatibility JavaVersion.VERSION_1_8
104
+ targetCompatibility JavaVersion.VERSION_1_8
105
+ }
106
+
107
+ sourceSets {
108
+ main {
109
+ java.srcDirs += [
110
+ "generated/java",
111
+ "generated/jni"
112
+ ]
113
+ }
114
+ }
115
+ }
116
+
117
+ repositories {
118
+ mavenCentral()
119
+ google()
120
+ }
121
+
122
+ def kotlin_version = getExtOrDefault("kotlinVersion")
123
+
124
+ dependencies {
125
+ implementation "com.facebook.react:react-android"
126
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
127
+ implementation project(":react-native-nitro-modules")
128
+ // WebViewAssetLoader + WebViewClientCompat for offline virtual same-origin
129
+ // hosting of the local chart bundle from the APK assets.
130
+ implementation "androidx.webkit:webkit:1.11.0"
131
+ }
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,6 @@
1
+ #include <jni.h>
2
+ #include "chartwebviewOnLoad.hpp"
3
+
4
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
5
+ return margelo::nitro::chartwebview::initialize(vm);
6
+ }
@@ -0,0 +1,331 @@
1
+ package com.margelo.nitro.chartwebview
2
+
3
+ import android.graphics.Bitmap
4
+ import android.view.View
5
+ import android.widget.FrameLayout
6
+ import android.widget.ImageView
7
+ import com.facebook.proguard.annotations.DoNotStrip
8
+ import com.facebook.react.uimanager.ThemedReactContext
9
+ import java.util.concurrent.atomic.AtomicInteger
10
+
11
+ /**
12
+ * Thin host for a chart WebView. It owns only a container [FrameLayout]; the
13
+ * real WebView lives in a [PooledChartWebView] which can be **shared** across
14
+ * hosts that use the same `reuseKey` (singleton via reparenting). The host:
15
+ *
16
+ * - claims the backing WebView into its container when it is attached AND
17
+ * active (`isActive != false`), and releases (detaches) it otherwise;
18
+ * - forwards page events to its Nitro callbacks while it is the active owner;
19
+ * - delegates `postMessage` / `reload` to the backing WebView.
20
+ *
21
+ * Ownership arbitration: native attach is the fast claim path; `isActive`
22
+ * (driven by JS `useIsFocused`) is the authoritative arbiter of who, among
23
+ * hosts sharing a key, currently displays the single WebView.
24
+ */
25
+ @DoNotStrip
26
+ class HybridChartWebview(val context: ThemedReactContext) : HybridChartWebviewSpec() {
27
+
28
+ companion object {
29
+ private val instanceIds = AtomicInteger(0)
30
+ // Substring of the chart's render-ready bridge message (method
31
+ // 'tradingview_renderReady'); cheaper than JSON-parsing every page message.
32
+ private const val RENDER_READY_MARKER = "tradingview_renderReady"
33
+ // Safety-net: reveal the live chart even if the render-ready signal is missed.
34
+ private const val REVEAL_FALLBACK_MS = 2000L
35
+ // The one host currently holding a snapshot over a switch, waiting for the
36
+ // render-ready signal. Shared so render-ready (which arrives on whichever host
37
+ // owns the WebView at that instant — not necessarily the awaiting one) reveals
38
+ // the correct host regardless of the owner-handoff timing.
39
+ private var pendingRevealHost: HybridChartWebview? = null
40
+ }
41
+
42
+ private val instanceId = instanceIds.incrementAndGet()
43
+
44
+ // Fabric lays its views out top-down and ignores layout requests from children
45
+ // we add at runtime (the WebView / placeholder). Without forcing a measure +
46
+ // layout pass here, those children stay 0x0 and the slot renders blank. This
47
+ // requestLayout override is the standard RN fix for custom ViewGroups.
48
+ private inner class ChartContainer(ctx: android.content.Context) : FrameLayout(ctx) {
49
+ private val relayout = Runnable {
50
+ measure(
51
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
52
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
53
+ )
54
+ layout(left, top, right, bottom)
55
+ }
56
+
57
+ override fun requestLayout() {
58
+ super.requestLayout()
59
+ post(relayout)
60
+ }
61
+ }
62
+
63
+ private val container: FrameLayout = ChartContainer(context).apply {
64
+ addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
65
+ override fun onViewAttachedToWindow(v: View) {
66
+ attached = true
67
+ scheduleReconcile()
68
+ }
69
+
70
+ override fun onViewDetachedFromWindow(v: View) {
71
+ attached = false
72
+ reconcile()
73
+ }
74
+ })
75
+ }
76
+
77
+ override val view: View = container
78
+
79
+ /** The WebView backing this host (a shared pool entry, or a private one). */
80
+ private var backing: PooledChartWebView? = null
81
+ private var attached = false
82
+
83
+ // --- Source props ---
84
+
85
+ private var _uri: String? = null
86
+ override var uri: String?
87
+ get() = _uri
88
+ set(value) { _uri = value; applySourceIfOwner() }
89
+
90
+ private var _localBundle: String? = null
91
+ override var localBundle: String?
92
+ get() = _localBundle
93
+ set(value) { _localBundle = value; applySourceIfOwner() }
94
+
95
+ private var _entry: String? = null
96
+ override var entry: String?
97
+ get() = _entry
98
+ set(value) { _entry = value; applySourceIfOwner() }
99
+
100
+ private var _paramsJson: String? = null
101
+ override var paramsJson: String?
102
+ get() = _paramsJson
103
+ set(value) { _paramsJson = value; applySourceIfOwner() }
104
+
105
+ // Document-start bridge JS (single source of truth in the TS layer). Stored and
106
+ // handed to the pooled WebView when we claim it, before its first load.
107
+ private var _bridgeScript: String? = null
108
+ override var bridgeScript: String?
109
+ get() = _bridgeScript
110
+ // Re-apply the source: if this prop lands after the source props (a load can't
111
+ // run before the bridge is registered, so setSource deferred), this triggers it.
112
+ set(value) { _bridgeScript = value; applySourceIfOwner() }
113
+
114
+ // --- Singleton props ---
115
+ // `pooled` + non-empty `reuseKey` => the backing WebView is shared (keyed by
116
+ // reuseKey) across hosts; otherwise the host owns a private WebView.
117
+ private var _reuseKey: String? = null
118
+ override var reuseKey: String?
119
+ get() = _reuseKey
120
+ set(value) { _reuseKey = value; scheduleReconcile() }
121
+
122
+ private var _pooled: Boolean? = null
123
+ override var pooled: Boolean?
124
+ get() = _pooled
125
+ set(value) { _pooled = value; scheduleReconcile() }
126
+
127
+ // `active` (JS useIsFocused) decides which host, among those sharing a key,
128
+ // owns the single WebView. null is treated as active (single-host case).
129
+ private var _active: Boolean? = null
130
+ override var active: Boolean?
131
+ get() = _active
132
+ set(value) {
133
+ val wasActive = _active != false
134
+ _active = value
135
+ // Becoming active: cover with our last frame NOW (synchronously, before the
136
+ // JS symbol-change fires this commit) and wait for the chart's render-ready,
137
+ // so the switch holds the snapshot until the new content paints. Doing it
138
+ // here rather than in the coalesced reconcile is essential — a cached symbol
139
+ // can render + signal before the posted reconcile even runs. ownSnapshot is
140
+ // non-null only for pooled hosts that have been shown before (first show
141
+ // just reveals the live WebView as it loads).
142
+ if (value != false && !wasActive && ownSnapshot != null) {
143
+ showPlaceholder(ownSnapshot)
144
+ awaitContentReveal()
145
+ }
146
+ scheduleReconcile()
147
+ }
148
+
149
+ // --- Event callbacks ---
150
+ override var onMessage: ((message: String) -> Unit)? = null
151
+ override var onLoadEnd: (() -> Unit)? = null
152
+ override var onError: ((message: String) -> Unit)? = null
153
+
154
+ // Called by the backing PooledChartWebView while this host is the owner.
155
+ fun dispatchMessage(message: String) {
156
+ // The chart reports it has painted the new symbol after a switch; that's our
157
+ // cue to drop the snapshot we held over the switch and reveal the live chart.
158
+ if (message.contains(RENDER_READY_MARKER)) onContentRendered()
159
+ onMessage?.invoke(message)
160
+ }
161
+ fun dispatchLoadEnd() { onLoadEnd?.invoke() }
162
+ fun dispatchError(message: String) { onError?.invoke(message) }
163
+
164
+ // --- Methods ---
165
+ override fun postMessage(message: String) { backing?.postMessage(message) }
166
+ override fun reload() { backing?.reload() }
167
+ override fun clearSnapshot() { backing?.clearSnapshot() }
168
+
169
+ // --- Ownership reconciliation ---
170
+
171
+ private fun isPooled(): Boolean = (_pooled == true) && !_reuseKey.isNullOrEmpty()
172
+
173
+ private fun effectiveKey(): String =
174
+ if (isPooled()) _reuseKey!! else "private:$instanceId"
175
+
176
+ private fun wantsOwnership(): Boolean = attached && (_active != false)
177
+
178
+ // A single React commit applies props one at a time, so the intermediate
179
+ // states are inconsistent (e.g. `pooled` re-applied while `active` is still
180
+ // stale). Reacting to each setter synchronously makes the wrong host claim
181
+ // mid-commit. Coalesce to ONE reconcile at the end of the run-loop, by which
182
+ // point every prop in the commit holds its final value.
183
+ private var reconcileScheduled = false
184
+ private val reconcileRunnable = Runnable {
185
+ reconcileScheduled = false
186
+ reconcile()
187
+ }
188
+
189
+ private fun scheduleReconcile() {
190
+ if (reconcileScheduled) return
191
+ reconcileScheduled = true
192
+ container.post(reconcileRunnable)
193
+ }
194
+
195
+ private fun reconcile() {
196
+ if (isPooled()) reconcilePooled() else reconcilePrivate()
197
+ }
198
+
199
+ // Pooled: every host sharing the key references the one entry. The active host
200
+ // displays the live WebView; inactive hosts display the cached frame snapshot
201
+ // so their slot isn't blank (and the live WebView reparents on hand-off).
202
+ private fun reconcilePooled() {
203
+ val entry = ChartWebviewPool.acquireShared(effectiveKey(), context)
204
+ backing = entry
205
+ if (wantsOwnership()) {
206
+ entry.owner = this
207
+ // Register the document-start bridge before the first load (the prop is set
208
+ // by now; the pool may have been created earlier by a window-attach reconcile).
209
+ entry.setBridgeScript(_bridgeScript ?: "")
210
+ entry.attachTo(container)
211
+ entry.setSource(_uri, _localBundle, _entry, _paramsJson)
212
+ // Keep a fresh frame of OUR content while we own the WebView, so that when
213
+ // we later go inactive (and the shared WebView reloads the other slot's
214
+ // chart) our slot freezes to its own last frame, not the other content.
215
+ startOwnCapture()
216
+ // The snapshot hold/reveal over a switch is driven by the `active` setter +
217
+ // render-ready, not here. Just keep a held snapshot on top of the freshly
218
+ // attached WebView, or clear a stale one if we're not holding.
219
+ if (awaitingReveal) placeholder?.bringToFront() else removePlaceholder()
220
+ } else {
221
+ // Inactive: give up ownership only if we still hold it, and freeze to our
222
+ // own last captured frame. We do NOT detach (that races a rapid re-claim).
223
+ val wasOwner = entry.owner == this
224
+ if (wasOwner) entry.owner = null
225
+ stopOwnCapture()
226
+ showPlaceholder(ownSnapshot)
227
+ }
228
+ }
229
+
230
+ // Non-pooled: a private WebView, claimed when active, kept on this host so a
231
+ // later re-claim reuses it without a reload. No placeholder (single host).
232
+ private fun reconcilePrivate() {
233
+ if (!wantsOwnership()) return
234
+ val pooled = backing ?: PooledChartWebView.create(context, effectiveKey())
235
+ backing = pooled
236
+ pooled.owner = this
237
+ pooled.setBridgeScript(_bridgeScript ?: "")
238
+ pooled.attachTo(container)
239
+ pooled.setSource(_uri, _localBundle, _entry, _paramsJson)
240
+ }
241
+
242
+ private fun applySourceIfOwner() {
243
+ val pooled = backing ?: return
244
+ if (pooled.owner == this) {
245
+ // Register the bridge before any load setSource may trigger (setSource
246
+ // defers loading until the bridge is registered).
247
+ pooled.setBridgeScript(_bridgeScript ?: "")
248
+ pooled.setSource(_uri, _localBundle, _entry, _paramsJson)
249
+ }
250
+ }
251
+
252
+ // --- Per-host snapshot (this host's own last frame, shown while inactive) ---
253
+
254
+ private var placeholder: ImageView? = null
255
+ // OUR content's last frame. Because the WebView is shared and reloads other
256
+ // slots' charts, we can't read the snapshot off the pooled entry — we keep our
257
+ // own, captured periodically while we own the WebView.
258
+ private var ownSnapshot: Bitmap? = null
259
+
260
+ private val ownCaptureRunnable = object : Runnable {
261
+ override fun run() {
262
+ val entry = backing ?: return
263
+ if (entry.owner != this@HybridChartWebview) return
264
+ // Late async results are dropped if we've meanwhile yielded ownership, so
265
+ // ownSnapshot only ever holds a frame captured while WE were showing.
266
+ entry.captureNow { bmp ->
267
+ if (bmp != null && entry.owner == this@HybridChartWebview) ownSnapshot = bmp
268
+ }
269
+ container.postDelayed(this, 1200)
270
+ }
271
+ }
272
+
273
+ private fun startOwnCapture() {
274
+ container.removeCallbacks(ownCaptureRunnable)
275
+ container.postDelayed(ownCaptureRunnable, 500)
276
+ }
277
+
278
+ private fun stopOwnCapture() {
279
+ container.removeCallbacks(ownCaptureRunnable)
280
+ }
281
+
282
+ // --- Reveal coordination: hold the snapshot over a switch until the chart
283
+ // reports the new symbol has painted (with a safety-net timeout). ---
284
+
285
+ private var awaitingReveal = false
286
+ private val revealFallbackRunnable = Runnable { doReveal() }
287
+
288
+ private fun awaitContentReveal() {
289
+ awaitingReveal = true
290
+ pendingRevealHost = this
291
+ container.removeCallbacks(revealFallbackRunnable)
292
+ // Safety net: if the render-ready signal never arrives, reveal anyway so the
293
+ // slot can't get stuck on the snapshot.
294
+ container.postDelayed(revealFallbackRunnable, REVEAL_FALLBACK_MS)
295
+ }
296
+
297
+ // The chart signalled the post-switch render is done (see dispatchMessage).
298
+ // Reveal whichever host is holding a snapshot — render-ready may land on a
299
+ // different host than the one waiting, depending on owner-handoff timing.
300
+ private fun onContentRendered() {
301
+ pendingRevealHost?.doReveal()
302
+ }
303
+
304
+ private fun doReveal() {
305
+ if (!awaitingReveal) return
306
+ awaitingReveal = false
307
+ if (pendingRevealHost == this) pendingRevealHost = null
308
+ container.removeCallbacks(revealFallbackRunnable)
309
+ removePlaceholder()
310
+ }
311
+
312
+ private fun showPlaceholder(bmp: Bitmap?) {
313
+ if (bmp == null) return
314
+ val iv = placeholder ?: ImageView(context).apply {
315
+ scaleType = ImageView.ScaleType.FIT_XY
316
+ layoutParams = FrameLayout.LayoutParams(
317
+ FrameLayout.LayoutParams.MATCH_PARENT,
318
+ FrameLayout.LayoutParams.MATCH_PARENT,
319
+ )
320
+ container.addView(this)
321
+ placeholder = this
322
+ }
323
+ iv.setImageBitmap(bmp)
324
+ iv.bringToFront()
325
+ }
326
+
327
+ private fun removePlaceholder() {
328
+ placeholder?.let { container.removeView(it) }
329
+ placeholder = null
330
+ }
331
+ }
@@ -0,0 +1,29 @@
1
+ package com.margelo.nitro.chartwebview
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfoProvider
7
+ import com.facebook.react.uimanager.ViewManager
8
+
9
+ import com.margelo.nitro.chartwebview.views.HybridChartWebviewManager
10
+
11
+ class ChartWebviewPackage : BaseReactPackage() {
12
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
13
+ return null
14
+ }
15
+
16
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
17
+ return ReactModuleInfoProvider { HashMap() }
18
+ }
19
+
20
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
21
+ return listOf(HybridChartWebviewManager())
22
+ }
23
+
24
+ companion object {
25
+ init {
26
+ System.loadLibrary("chartwebview")
27
+ }
28
+ }
29
+ }