@azzapp/react-native-snapshot-view 0.1.4 → 0.3.0
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.
- package/README.md +3 -2
- package/android/build.gradle +13 -59
- package/android/gradle.properties +5 -5
- package/android/src/main/AndroidManifest.xml +1 -2
- package/android/src/main/java/com/azzapp/rnsnapshotview/RNSnapshotRendererManager.kt +15 -4
- package/android/src/main/java/com/azzapp/rnsnapshotview/ReactNativeSnapshotViewModule.kt +54 -25
- package/android/src/main/java/com/azzapp/rnsnapshotview/ReactNativeSnapshotViewPackage.kt +2 -6
- package/azzapp-react-native-snapshot-view.podspec +2 -23
- package/ios/RNSnapshotRenderer.h +0 -3
- package/ios/RNSnapshotRenderer.mm +9 -6
- package/ios/RNSnapshotView.h +2 -8
- package/ios/RNSnapshotView.mm +85 -41
- package/lib/module/NativeRNSnapshotView.js.map +1 -1
- package/lib/module/RNSnapshotRendererNativeComponent.ts +7 -0
- package/lib/module/SnapshotRenderer.js +4 -5
- package/lib/module/SnapshotRenderer.js.map +1 -1
- package/lib/module/index.js +22 -15
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeRNSnapshotView.d.ts +2 -0
- package/lib/typescript/src/NativeRNSnapshotView.d.ts.map +1 -1
- package/lib/typescript/src/RNSnapshotRendererNativeComponent.d.ts +2 -2
- package/lib/typescript/src/RNSnapshotRendererNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/SnapshotRenderer.d.ts +6 -14
- package/lib/typescript/src/SnapshotRenderer.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +41 -53
- package/react-native.config.js +4 -0
- package/src/NativeRNSnapshotView.ts +2 -0
- package/src/RNSnapshotRendererNativeComponent.ts +1 -2
- package/src/SnapshotRenderer.tsx +9 -10
- package/src/index.tsx +21 -25
- package/android/src/main/AndroidManifestNew.xml +0 -2
- package/android/src/newarch/RNSnapshotRendererManagerSpec.kt +0 -21
- package/android/src/newarch/RNSnapshotViewSpec.kt +0 -7
- package/android/src/oldarch/RNSnapshotRendererManagerSpec.kt +0 -9
- package/android/src/oldarch/RNSnapshotViewSpec.kt +0 -12
- package/ios/RNSnapshotRendererManager.mm +0 -62
- package/lib/module/RNSnapshotRendererNativeComponent.js +0 -5
- package/lib/module/RNSnapshotRendererNativeComponent.js.map +0 -1
package/README.md
CHANGED
|
@@ -25,10 +25,11 @@ const snapshotID = await captureSnapshot(viewRef.current);
|
|
|
25
25
|
|
|
26
26
|
>:warning: captured snapshot are kept in memory, either use `releaseSnapshot` to release them, or let the `SnapshotRenderer` component release the snapshot on unmount.
|
|
27
27
|
|
|
28
|
-
|
|
29
28
|
## Contributing
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
- [Development workflow](CONTRIBUTING.md#development-workflow)
|
|
31
|
+
- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
|
|
32
|
+
- [Code of conduct](CODE_OF_CONDUCT.md)
|
|
32
33
|
|
|
33
34
|
## License
|
|
34
35
|
|
package/android/build.gradle
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
buildscript {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ext.getExtOrDefault = {name ->
|
|
3
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ReactNativeSnapshotView_' + name]
|
|
4
|
+
}
|
|
4
5
|
|
|
5
6
|
repositories {
|
|
6
7
|
google()
|
|
@@ -8,63 +9,30 @@ buildscript {
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
dependencies {
|
|
11
|
-
classpath "com.android.tools.build:gradle:7.2
|
|
12
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
12
13
|
// noinspection DifferentKotlinGradleVersion
|
|
13
|
-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$
|
|
14
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
def reactNativeArchitectures() {
|
|
18
|
-
def value = rootProject.getProperties().get("reactNativeArchitectures")
|
|
19
|
-
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
def isNewArchitectureEnabled() {
|
|
23
|
-
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
24
|
-
}
|
|
25
18
|
|
|
26
19
|
apply plugin: "com.android.library"
|
|
27
20
|
apply plugin: "kotlin-android"
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
apply plugin: "com.facebook.react"
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
def getExtOrDefault(name) {
|
|
34
|
-
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["ReactNativeSnapshotView_" + name]
|
|
35
|
-
}
|
|
22
|
+
apply plugin: "com.facebook.react"
|
|
36
23
|
|
|
37
24
|
def getExtOrIntegerDefault(name) {
|
|
38
|
-
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
def supportsNamespace() {
|
|
42
|
-
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
|
|
43
|
-
def major = parsed[0].toInteger()
|
|
44
|
-
def minor = parsed[1].toInteger()
|
|
45
|
-
|
|
46
|
-
// Namespace support was added in 7.3.0
|
|
47
|
-
return (major == 7 && minor >= 3) || major >= 8
|
|
25
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["SnapshotView_" + name]).toInteger()
|
|
48
26
|
}
|
|
49
27
|
|
|
50
28
|
android {
|
|
51
|
-
|
|
52
|
-
namespace "com.azzapp.rnsnapshotview"
|
|
53
|
-
|
|
54
|
-
sourceSets {
|
|
55
|
-
main {
|
|
56
|
-
manifest.srcFile "src/main/AndroidManifestNew.xml"
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
29
|
+
namespace "com.azzapp.rnsnapshotview"
|
|
60
30
|
|
|
61
31
|
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
62
32
|
|
|
63
33
|
defaultConfig {
|
|
64
34
|
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
65
35
|
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
66
|
-
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
67
|
-
|
|
68
36
|
}
|
|
69
37
|
|
|
70
38
|
buildFeatures {
|
|
@@ -88,13 +56,10 @@ android {
|
|
|
88
56
|
|
|
89
57
|
sourceSets {
|
|
90
58
|
main {
|
|
91
|
-
|
|
92
|
-
java
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
} else {
|
|
96
|
-
java.srcDirs += ["src/oldarch"]
|
|
97
|
-
}
|
|
59
|
+
java.srcDirs += [
|
|
60
|
+
"generated/java",
|
|
61
|
+
"generated/jni"
|
|
62
|
+
]
|
|
98
63
|
}
|
|
99
64
|
}
|
|
100
65
|
}
|
|
@@ -107,17 +72,6 @@ repositories {
|
|
|
107
72
|
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
108
73
|
|
|
109
74
|
dependencies {
|
|
110
|
-
|
|
111
|
-
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
|
|
112
|
-
//noinspection GradleDynamicVersion
|
|
113
|
-
implementation "com.facebook.react:react-native:+"
|
|
75
|
+
implementation "com.facebook.react:react-android"
|
|
114
76
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
115
77
|
}
|
|
116
|
-
|
|
117
|
-
if (isNewArchitectureEnabled()) {
|
|
118
|
-
react {
|
|
119
|
-
jsRootDir = file("../src/")
|
|
120
|
-
libraryName = "ReactNativeSnapshotViewView"
|
|
121
|
-
codegenJavaPackageName = "com.azzapp.rnsnapshotview"
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
ReactNativeSnapshotView_kotlinVersion=
|
|
2
|
-
ReactNativeSnapshotView_minSdkVersion=
|
|
3
|
-
ReactNativeSnapshotView_targetSdkVersion=
|
|
4
|
-
ReactNativeSnapshotView_compileSdkVersion=
|
|
5
|
-
|
|
1
|
+
ReactNativeSnapshotView_kotlinVersion=2.0.21
|
|
2
|
+
ReactNativeSnapshotView_minSdkVersion=24
|
|
3
|
+
ReactNativeSnapshotView_targetSdkVersion=34
|
|
4
|
+
ReactNativeSnapshotView_compileSdkVersion=35
|
|
5
|
+
ReactNativeSnapshotView_ndkVersion=27.1.12297006
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
package com.azzapp.rnsnapshotview
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import android.graphics.Color
|
|
5
3
|
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.SimpleViewManager
|
|
6
5
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
7
7
|
import com.facebook.react.uimanager.annotations.ReactProp
|
|
8
|
+
import com.facebook.react.viewmanagers.RNSnapshotRendererManagerInterface
|
|
9
|
+
import com.facebook.react.viewmanagers.RNSnapshotRendererManagerDelegate
|
|
8
10
|
|
|
9
11
|
@ReactModule(name = RNSnapshotRendererManager.NAME)
|
|
10
|
-
class RNSnapshotRendererManager :
|
|
11
|
-
|
|
12
|
+
class RNSnapshotRendererManager : SimpleViewManager<RNSnapshotRenderer>(),
|
|
13
|
+
RNSnapshotRendererManagerInterface<RNSnapshotRenderer> {
|
|
14
|
+
private val mDelegate: ViewManagerDelegate<RNSnapshotRenderer>
|
|
15
|
+
init {
|
|
16
|
+
mDelegate = RNSnapshotRendererManagerDelegate(this)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getDelegate(): ViewManagerDelegate<RNSnapshotRenderer>? {
|
|
20
|
+
return mDelegate
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
override fun getName(): String {
|
|
13
24
|
return NAME
|
|
14
25
|
}
|
|
@@ -19,10 +19,7 @@ import com.facebook.react.bridge.ReactApplicationContext
|
|
|
19
19
|
import com.facebook.react.bridge.ReactMethod
|
|
20
20
|
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
|
21
21
|
import com.facebook.react.fabric.FabricUIManager
|
|
22
|
-
import com.facebook.react.uimanager.NativeViewHierarchyManager
|
|
23
|
-
import com.facebook.react.uimanager.UIBlock
|
|
24
22
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
25
|
-
import com.facebook.react.uimanager.UIManagerModule
|
|
26
23
|
import com.facebook.react.uimanager.common.UIManagerType
|
|
27
24
|
import java.util.Collections
|
|
28
25
|
import java.util.LinkedList
|
|
@@ -32,7 +29,7 @@ import java.util.concurrent.TimeUnit
|
|
|
32
29
|
|
|
33
30
|
|
|
34
31
|
class ReactNativeSnapshotViewModule internal constructor(context: ReactApplicationContext) :
|
|
35
|
-
|
|
32
|
+
NativeRNSnapshotViewSpec(context) {
|
|
36
33
|
|
|
37
34
|
override fun getName(): String {
|
|
38
35
|
return NAME
|
|
@@ -59,30 +56,62 @@ class ReactNativeSnapshotViewModule internal constructor(context: ReactApplicati
|
|
|
59
56
|
}
|
|
60
57
|
}
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
val uiManager = UIManagerHelper.getUIManager(reactApplicationContext, UIManagerType.FABRIC)
|
|
60
|
+
if (uiManager !is FabricUIManager) {
|
|
61
|
+
promise.reject("not_found", "Cannot obtain UIManager")
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
uiManager.addUIBlock { uiBlockViewResolver ->
|
|
66
|
+
val view = uiBlockViewResolver.resolveView(viewTag.toInt())
|
|
67
|
+
handleView(view)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@ReactMethod
|
|
72
|
+
override fun snapshotScreen(promise: Promise) {
|
|
73
|
+
val activity = reactApplicationContext.currentActivity
|
|
74
|
+
if (activity == null) {
|
|
75
|
+
promise.reject("not_found", "Activity not found")
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
val window = activity.window
|
|
79
|
+
if (window == null) {
|
|
80
|
+
promise.reject("not_found", "Window not found")
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
val decorView = window.decorView
|
|
84
|
+
val bitmap = Bitmap.createBitmap(decorView.width, decorView.height, Bitmap.Config.ARGB_8888)
|
|
85
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
86
|
+
PixelCopy.request(window, bitmap, { result ->
|
|
87
|
+
if (result == PixelCopy.SUCCESS) {
|
|
88
|
+
val uuid = UUID.randomUUID().toString()
|
|
89
|
+
snapshotMap[uuid] = bitmap
|
|
90
|
+
promise.resolve(uuid)
|
|
91
|
+
} else {
|
|
92
|
+
bitmap.recycle()
|
|
93
|
+
promise.reject("snapshot_failed", "PixelCopy failed with result $result")
|
|
68
94
|
}
|
|
69
|
-
}
|
|
70
|
-
promise.reject("not_found", "Cannot obtain UIManager")
|
|
71
|
-
return
|
|
72
|
-
}
|
|
95
|
+
}, Handler(Looper.getMainLooper()))
|
|
73
96
|
} else {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
97
|
+
decorView.draw(Canvas(bitmap))
|
|
98
|
+
val uuid = UUID.randomUUID().toString()
|
|
99
|
+
snapshotMap[uuid] = bitmap
|
|
100
|
+
promise.resolve(uuid)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@ReactMethod
|
|
105
|
+
override fun duplicateSnapshot(snapshotID: String, promise: Promise) {
|
|
106
|
+
val original = snapshotMap[snapshotID]
|
|
107
|
+
if (original == null) {
|
|
108
|
+
promise.reject("not_found", "Snapshot not found")
|
|
109
|
+
return
|
|
85
110
|
}
|
|
111
|
+
val copy = original.copy(original.config ?: Bitmap.Config.ARGB_8888, false)
|
|
112
|
+
val uuid = UUID.randomUUID().toString()
|
|
113
|
+
snapshotMap[uuid] = copy
|
|
114
|
+
promise.resolve(uuid)
|
|
86
115
|
}
|
|
87
116
|
|
|
88
117
|
@ReactMethod
|
|
@@ -6,7 +6,6 @@ import com.facebook.react.bridge.ReactApplicationContext
|
|
|
6
6
|
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
7
|
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
8
|
import com.facebook.react.uimanager.ViewManager
|
|
9
|
-
import java.util.ArrayList
|
|
10
9
|
import java.util.HashMap
|
|
11
10
|
|
|
12
11
|
class ReactNativeSnapshotViewPackage : TurboReactPackage() {
|
|
@@ -21,7 +20,6 @@ class ReactNativeSnapshotViewPackage : TurboReactPackage() {
|
|
|
21
20
|
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
22
21
|
return ReactModuleInfoProvider {
|
|
23
22
|
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
|
|
24
|
-
val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
|
25
23
|
moduleInfos[ReactNativeSnapshotViewModule.NAME] = ReactModuleInfo(
|
|
26
24
|
ReactNativeSnapshotViewModule.NAME,
|
|
27
25
|
ReactNativeSnapshotViewModule.NAME,
|
|
@@ -29,14 +27,12 @@ class ReactNativeSnapshotViewPackage : TurboReactPackage() {
|
|
|
29
27
|
false, // needsEagerInit
|
|
30
28
|
true, // hasConstants
|
|
31
29
|
false, // isCxxModule
|
|
32
|
-
|
|
30
|
+
true // isTurboModule
|
|
33
31
|
)
|
|
34
32
|
moduleInfos
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
38
|
-
|
|
39
|
-
viewManagers.add(RNSnapshotRendererManager())
|
|
40
|
-
return viewManagers
|
|
36
|
+
return listOf(RNSnapshotRendererManager())
|
|
41
37
|
}
|
|
42
38
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require "json"
|
|
2
2
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
-
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
|
5
4
|
|
|
6
5
|
Pod::Spec.new do |s|
|
|
7
6
|
s.name = "azzapp-react-native-snapshot-view"
|
|
@@ -15,28 +14,8 @@ Pod::Spec.new do |s|
|
|
|
15
14
|
s.source = { :git => "https://github.com/AzzappApp/react-native-snapshot-view.git", :tag => "#{s.version}" }
|
|
16
15
|
|
|
17
16
|
s.source_files = "ios/**/*.{h,m,mm,cpp}"
|
|
17
|
+
s.private_header_files = "ios/**/*.h"
|
|
18
18
|
|
|
19
|
-
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
20
|
-
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
|
21
|
-
if respond_to?(:install_modules_dependencies, true)
|
|
22
|
-
install_modules_dependencies(s)
|
|
23
|
-
else
|
|
24
|
-
s.dependency "React-Core"
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
|
|
28
|
-
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
|
|
29
|
-
s.pod_target_xcconfig = {
|
|
30
|
-
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
|
|
31
|
-
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
|
|
32
|
-
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
|
|
33
|
-
}
|
|
34
|
-
s.dependency "React-RCTFabric"
|
|
35
|
-
s.dependency "React-Codegen"
|
|
36
|
-
s.dependency "RCT-Folly"
|
|
37
|
-
s.dependency "RCTRequired"
|
|
38
|
-
s.dependency "RCTTypeSafety"
|
|
39
|
-
s.dependency "ReactCommon/turbomodule/core"
|
|
40
|
-
end
|
|
41
|
-
end
|
|
20
|
+
install_modules_dependencies(s)
|
|
42
21
|
end
|
package/ios/RNSnapshotRenderer.h
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// This guard prevent this file to be compiled in the old architecture.
|
|
2
|
-
#ifdef RCT_NEW_ARCH_ENABLED
|
|
3
1
|
#import <React/RCTViewComponentView.h>
|
|
4
2
|
#import <UIKit/UIKit.h>
|
|
5
3
|
|
|
@@ -14,4 +12,3 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
14
12
|
NS_ASSUME_NONNULL_END
|
|
15
13
|
|
|
16
14
|
#endif /* RNSnapshotRendererNativeComponent_h */
|
|
17
|
-
#endif /* RCT_NEW_ARCH_ENABLED */
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
1
|
#import "RNSnapshotRenderer.h"
|
|
3
2
|
|
|
4
3
|
#import <react/renderer/components/RNSnapshotViewSpec/ComponentDescriptors.h>
|
|
@@ -44,9 +43,14 @@ using namespace facebook::react;
|
|
|
44
43
|
const auto &newViewProps = *std::static_pointer_cast<RNSnapshotRendererProps const>(props);
|
|
45
44
|
|
|
46
45
|
if (oldViewProps.snapshotID != newViewProps.snapshotID) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
NSString *identifier = [NSString stringWithUTF8String:newViewProps.snapshotID.c_str()];
|
|
47
|
+
if (identifier.length == 0) {
|
|
48
|
+
self.contentView = nil;
|
|
49
|
+
} else {
|
|
50
|
+
UIView *snapshot = [RNSnapshotView getSnapShotMap][identifier];
|
|
51
|
+
[snapshot removeFromSuperview];
|
|
52
|
+
self.contentView = snapshot;
|
|
53
|
+
}
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
[super updateProps:props oldProps:oldProps];
|
|
@@ -57,5 +61,4 @@ Class<RCTComponentViewProtocol> RNSnapshotRendererCls(void)
|
|
|
57
61
|
return RNSnapshotRenderer.class;
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
@end
|
|
61
|
-
#endif
|
|
64
|
+
@end
|
package/ios/RNSnapshotView.h
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
#ifdef RCT_NEW_ARCH_ENABLED
|
|
3
2
|
#import "RNSnapshotViewSpec.h"
|
|
3
|
+
#import <UIKit/UIKit.h>
|
|
4
4
|
|
|
5
5
|
@interface RNSnapshotView : NSObject <NativeRNSnapshotViewSpec>
|
|
6
|
-
#else
|
|
7
|
-
#import <React/RCTBridgeModule.h>
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
#endif
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
+(NSDictionary<NSString*, UIView *> *)getSnapShotMap;
|
|
7
|
+
+ (NSMutableDictionary<NSString *, UIView *> *)getSnapShotMap;
|
|
14
8
|
|
|
15
9
|
@end
|
package/ios/RNSnapshotView.mm
CHANGED
|
@@ -1,71 +1,115 @@
|
|
|
1
1
|
#import "RNSnapshotView.h"
|
|
2
|
-
|
|
3
|
-
#if __has_include(<React/RCTUIManagerUtils.h>)
|
|
4
|
-
#import <React/RCTUIManagerUtils.h>
|
|
5
|
-
#endif
|
|
2
|
+
|
|
6
3
|
#import <React/RCTBridge.h>
|
|
4
|
+
#import <React/RCTBridge+Private.h>
|
|
5
|
+
#import <React/RCTUIManager.h>
|
|
7
6
|
|
|
8
7
|
@implementation RNSnapshotView
|
|
9
8
|
RCT_EXPORT_MODULE()
|
|
10
9
|
|
|
11
10
|
@synthesize bridge = _bridge;
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
return RCTGetUIManagerQueue();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
static NSMutableDictionary<NSString*, UIView *> *snapshotMap;
|
|
12
|
+
static NSMutableDictionary<NSString *, UIView *> *snapshotMap;
|
|
19
13
|
|
|
20
|
-
+(
|
|
14
|
+
+ (NSMutableDictionary<NSString *, UIView *> *)getSnapShotMap
|
|
15
|
+
{
|
|
21
16
|
if (snapshotMap == nil) {
|
|
22
17
|
snapshotMap = [[NSMutableDictionary alloc] init];
|
|
23
18
|
}
|
|
24
19
|
return snapshotMap;
|
|
25
20
|
}
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
UIView *view =
|
|
33
|
-
if (view
|
|
34
|
-
UIView *snapshot = [view snapshotViewAfterScreenUpdates:NO];
|
|
35
|
-
if (snapshotMap == nil) {
|
|
36
|
-
snapshotMap = [[NSMutableDictionary alloc] init];
|
|
37
|
-
}
|
|
38
|
-
NSUUID *uuid = [NSUUID UUID];
|
|
39
|
-
NSString *str = [uuid UUIDString];
|
|
40
|
-
[snapshotMap setValue:snapshot forKey:str];
|
|
41
|
-
resolve(str);
|
|
42
|
-
} else {
|
|
22
|
+
- (void)captureSnapshot:(double)viewTag
|
|
23
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
24
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
25
|
+
{
|
|
26
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
27
|
+
UIView *view = [self viewForReactTag:viewTag];
|
|
28
|
+
if (view == nil) {
|
|
43
29
|
reject(@"not_found", @"View not found", nil);
|
|
30
|
+
return;
|
|
44
31
|
}
|
|
45
|
-
|
|
32
|
+
|
|
33
|
+
UIView *snapshot = [view snapshotViewAfterScreenUpdates:NO];
|
|
34
|
+
if (snapshot == nil) {
|
|
35
|
+
reject(@"snapshot_failed", @"Failed to capture snapshot", nil);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
NSString *identifier = [[NSUUID UUID] UUIDString];
|
|
40
|
+
[[RNSnapshotView getSnapShotMap] setObject:snapshot forKey:identifier];
|
|
41
|
+
resolve(identifier);
|
|
42
|
+
});
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
- (void)snapshotScreen:(RCTPromiseResolveBlock)resolve
|
|
46
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
47
|
+
{
|
|
48
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
49
|
+
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
|
|
50
|
+
if (window == nil) {
|
|
51
|
+
reject(@"not_found", @"Key window not found", nil);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
UIView *snapshot = [window snapshotViewAfterScreenUpdates:NO];
|
|
56
|
+
if (snapshot == nil) {
|
|
57
|
+
reject(@"snapshot_failed", @"Failed to capture screen snapshot", nil);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
NSString *identifier = [[NSUUID UUID] UUIDString];
|
|
62
|
+
[[RNSnapshotView getSnapShotMap] setObject:snapshot forKey:identifier];
|
|
63
|
+
resolve(identifier);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
- (void)duplicateSnapshot:(NSString *)snapshotID
|
|
68
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
69
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
70
|
+
{
|
|
71
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
72
|
+
UIView *original = [[RNSnapshotView getSnapShotMap] objectForKey:snapshotID];
|
|
73
|
+
if (original == nil) {
|
|
74
|
+
reject(@"not_found", @"Snapshot not found", nil);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
UIView *duplicate = [original snapshotViewAfterScreenUpdates:NO];
|
|
79
|
+
if (duplicate == nil) {
|
|
80
|
+
reject(@"snapshot_failed", @"Failed to duplicate snapshot", nil);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
NSString *identifier = [[NSUUID UUID] UUIDString];
|
|
85
|
+
[[RNSnapshotView getSnapShotMap] setObject:duplicate forKey:identifier];
|
|
86
|
+
resolve(identifier);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
- (void)releaseSnapshot:(NSString *)uuid
|
|
91
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
92
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
93
|
+
{
|
|
52
94
|
if (uuid != nil) {
|
|
53
|
-
|
|
54
|
-
snapshotMap = [[NSMutableDictionary alloc] init];
|
|
55
|
-
}
|
|
56
|
-
[snapshotMap removeObjectForKey:uuid];
|
|
95
|
+
[[RNSnapshotView getSnapShotMap] removeObjectForKey:uuid];
|
|
57
96
|
}
|
|
58
97
|
resolve(nil);
|
|
59
98
|
}
|
|
60
99
|
|
|
61
|
-
|
|
62
|
-
|
|
100
|
+
- (UIView *)viewForReactTag:(double)viewTag
|
|
101
|
+
{
|
|
102
|
+
RCTUIManager* uiManager = self.bridge.uiManager;
|
|
103
|
+
if (uiManager == nil) {
|
|
104
|
+
return nil;
|
|
105
|
+
}
|
|
106
|
+
return [uiManager viewForReactTag:[NSNumber numberWithDouble:viewTag]];
|
|
107
|
+
}
|
|
108
|
+
|
|
63
109
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
64
110
|
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
65
111
|
{
|
|
66
|
-
|
|
112
|
+
return std::make_shared<facebook::react::NativeRNSnapshotViewSpecJSI>(params);
|
|
67
113
|
}
|
|
68
|
-
#endif
|
|
69
|
-
|
|
70
114
|
|
|
71
115
|
@end
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeRNSnapshotView.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeRNSnapshotView.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AASlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,gBAAgB,CAAC","ignoreList":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
4
|
import RNSnapshotRenderer from './RNSnapshotRendererNativeComponent';
|
|
5
|
-
import { releaseSnapshot } from
|
|
5
|
+
import { releaseSnapshot } from "./index.js";
|
|
6
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
7
|
/**
|
|
8
8
|
* A view that renders a snapshot of a view.
|
|
@@ -11,7 +11,7 @@ const SnapshotRenderer = ({
|
|
|
11
11
|
snapshotID,
|
|
12
12
|
autoReleaseSnapshot = true,
|
|
13
13
|
...props
|
|
14
|
-
}
|
|
14
|
+
}) => {
|
|
15
15
|
const autoReleaseSnapshotRef = useRef(autoReleaseSnapshot);
|
|
16
16
|
useEffect(() => {
|
|
17
17
|
autoReleaseSnapshotRef.current = autoReleaseSnapshot;
|
|
@@ -22,10 +22,9 @@ const SnapshotRenderer = ({
|
|
|
22
22
|
}
|
|
23
23
|
}, [snapshotID]);
|
|
24
24
|
return /*#__PURE__*/_jsx(RNSnapshotRenderer, {
|
|
25
|
-
ref: forwardedRef,
|
|
26
25
|
snapshotID: snapshotID,
|
|
27
26
|
...props
|
|
28
27
|
});
|
|
29
28
|
};
|
|
30
|
-
export default
|
|
29
|
+
export default SnapshotRenderer;
|
|
31
30
|
//# sourceMappingURL=SnapshotRenderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","RNSnapshotRenderer","releaseSnapshot","jsx","_jsx","SnapshotRenderer","snapshotID","autoReleaseSnapshot","props","autoReleaseSnapshotRef","current","catch"],"sourceRoot":"../../src","sources":["SnapshotRenderer.tsx"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,QAAQ,OAAO;AAEzC,OAAOC,kBAAkB,MAAM,qCAAqC;AACpE,SAASC,eAAe,QAAQ,YAAG;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAepC;AACA;AACA;AACA,MAAMC,gBAAgB,GAAGA,CAAC;EACxBC,UAAU;EACVC,mBAAmB,GAAG,IAAI;EAC1B,GAAGC;AACkB,CAAC,KAAK;EAC3B,MAAMC,sBAAsB,GAAGT,MAAM,CAACO,mBAAmB,CAAC;EAC1DR,SAAS,CAAC,MAAM;IACdU,sBAAsB,CAACC,OAAO,GAAGH,mBAAmB;EACtD,CAAC,EAAE,CAACA,mBAAmB,CAAC,CAAC;EAEzBR,SAAS,CACP,MAAM,MAAM;IACV,IAAIU,sBAAsB,CAACC,OAAO,IAAIJ,UAAU,EAAE;MAChDJ,eAAe,CAACI,UAAU,CAAC,CAACK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C;EACF,CAAC,EACD,CAACL,UAAU,CACb,CAAC;EACD,oBAAOF,IAAA,CAACH,kBAAkB;IAACK,UAAU,EAAEA,UAAW;IAAA,GAAKE;EAAK,CAAG,CAAC;AAClE,CAAC;AAED,eAAeH,gBAAgB","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { findNodeHandle
|
|
4
|
-
|
|
5
|
-
ios: "- You have run 'pod install'\n",
|
|
6
|
-
default: ''
|
|
7
|
-
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
|
|
8
|
-
|
|
9
|
-
// @ts-expect-error
|
|
10
|
-
const isTurboModuleEnabled = global.__turboModuleProxy != null;
|
|
11
|
-
const RNSnapshotViewModule = isTurboModuleEnabled ? require('./NativeRNSnapshotView').default : NativeModules.RNSnapshotView;
|
|
12
|
-
const RNSnapshotView = RNSnapshotViewModule ? RNSnapshotViewModule : new Proxy({}, {
|
|
13
|
-
get() {
|
|
14
|
-
throw new Error(LINKING_ERROR);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
3
|
+
import { findNodeHandle } from 'react-native';
|
|
4
|
+
import RNSnapshotView from "./NativeRNSnapshotView.js";
|
|
17
5
|
|
|
18
6
|
/**
|
|
19
7
|
* Captures a snapshot of a view. The snapshot can be rendered using the `SnapshotRenderer` component.
|
|
@@ -29,6 +17,25 @@ export function captureSnapshot(componentOrHandle) {
|
|
|
29
17
|
return RNSnapshotView.captureSnapshot(handle);
|
|
30
18
|
}
|
|
31
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Captures a snapshot of the entire screen.
|
|
22
|
+
*
|
|
23
|
+
* @returns A promise that resolves to the ID of the snapshot. The snapshot should be released when no longer needed.
|
|
24
|
+
*/
|
|
25
|
+
export function snapshotScreen() {
|
|
26
|
+
return RNSnapshotView.snapshotScreen();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Duplicates a snapshot. The duplicate is independent and must be released separately.
|
|
31
|
+
*
|
|
32
|
+
* @param snapshotID The ID of the snapshot to duplicate.
|
|
33
|
+
* @returns A promise that resolves to the ID of the duplicated snapshot.
|
|
34
|
+
*/
|
|
35
|
+
export function duplicateSnapshot(snapshotID) {
|
|
36
|
+
return RNSnapshotView.duplicateSnapshot(snapshotID);
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
/**
|
|
33
40
|
* Releases a snapshot.
|
|
34
41
|
*
|
|
@@ -38,5 +45,5 @@ export function captureSnapshot(componentOrHandle) {
|
|
|
38
45
|
export function releaseSnapshot(snapshotID) {
|
|
39
46
|
return RNSnapshotView.releaseSnapshot(snapshotID);
|
|
40
47
|
}
|
|
41
|
-
export { default as SnapshotRenderer } from
|
|
48
|
+
export { default as SnapshotRenderer } from "./SnapshotRenderer.js";
|
|
42
49
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["findNodeHandle","
|
|
1
|
+
{"version":3,"names":["findNodeHandle","RNSnapshotView","captureSnapshot","componentOrHandle","handle","Promise","reject","Error","snapshotScreen","duplicateSnapshot","snapshotID","releaseSnapshot","default","SnapshotRenderer"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,cAAc;AAC7C,OAAOC,cAAc,MAAM,2BAAwB;;AAEnD;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BC,iBAI6B,EACZ;EACjB,MAAMC,MAAM,GAAGJ,cAAc,CAACG,iBAAiB,CAAC;EAChD,IAAIC,MAAM,IAAI,IAAI,EAAE;IAClB,OAAOC,OAAO,CAACC,MAAM,CAAC,IAAIC,KAAK,CAAC,qBAAqB,CAAC,CAAC;EACzD;EACA,OAAON,cAAc,CAACC,eAAe,CAACE,MAAM,CAAC;AAC/C;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASI,cAAcA,CAAA,EAAoB;EAChD,OAAOP,cAAc,CAACO,cAAc,CAAC,CAAC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAACC,UAAkB,EAAmB;EACrE,OAAOT,cAAc,CAACQ,iBAAiB,CAACC,UAAU,CAAC;AACrD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAACD,UAAkB,EAAiB;EACjE,OAAOT,cAAc,CAACU,eAAe,CAACD,UAAU,CAAC;AACnD;AAEA,SAASE,OAAO,IAAIC,gBAAgB,QAAQ,uBAAoB","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { TurboModule } from 'react-native';
|
|
2
2
|
export interface Spec extends TurboModule {
|
|
3
3
|
captureSnapshot(target: number): Promise<string>;
|
|
4
|
+
snapshotScreen(): Promise<string>;
|
|
5
|
+
duplicateSnapshot(snapshotID: string): Promise<string>;
|
|
4
6
|
releaseSnapshot(a: string): Promise<void>;
|
|
5
7
|
}
|
|
6
8
|
declare const _default: Spec;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeRNSnapshotView.d.ts","sourceRoot":"","sources":["../../../src/NativeRNSnapshotView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;;AAED,wBAAwE"}
|
|
1
|
+
{"version":3,"file":"NativeRNSnapshotView.d.ts","sourceRoot":"","sources":["../../../src/NativeRNSnapshotView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;;AAED,wBAAwE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ViewProps } from 'react-native';
|
|
2
2
|
interface NativeProps extends ViewProps {
|
|
3
3
|
snapshotID?: string | null;
|
|
4
4
|
}
|
|
5
|
-
declare const _default: import("react-native/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeProps>;
|
|
5
|
+
declare const _default: import("react-native/types_generated/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeProps>;
|
|
6
6
|
export default _default;
|
|
7
7
|
//# sourceMappingURL=RNSnapshotRendererNativeComponent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RNSnapshotRendererNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/RNSnapshotRendererNativeComponent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RNSnapshotRendererNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/RNSnapshotRendererNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtE,UAAU,WAAY,SAAQ,SAAS;IACrC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;;AAED,wBAAyE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ViewProps } from 'react-native';
|
|
2
2
|
export type SnapshotRendererProps = Omit<ViewProps, 'children'> & {
|
|
3
3
|
/**
|
|
4
4
|
* The ID of the snapshot to render.
|
|
@@ -11,17 +11,9 @@ export type SnapshotRendererProps = Omit<ViewProps, 'children'> & {
|
|
|
11
11
|
*/
|
|
12
12
|
autoReleaseSnapshot?: boolean;
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
snapshotID: string | null;
|
|
20
|
-
/**
|
|
21
|
-
* Whether to automatically release the snapshot when no longer displayed.
|
|
22
|
-
* @default true
|
|
23
|
-
*/
|
|
24
|
-
autoReleaseSnapshot?: boolean;
|
|
25
|
-
} & import("react").RefAttributes<View>>;
|
|
26
|
-
export default _default;
|
|
14
|
+
/**
|
|
15
|
+
* A view that renders a snapshot of a view.
|
|
16
|
+
*/
|
|
17
|
+
declare const SnapshotRenderer: ({ snapshotID, autoReleaseSnapshot, ...props }: SnapshotRendererProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export default SnapshotRenderer;
|
|
27
19
|
//# sourceMappingURL=SnapshotRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapshotRenderer.d.ts","sourceRoot":"","sources":["../../../src/SnapshotRenderer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"SnapshotRenderer.d.ts","sourceRoot":"","sources":["../../../src/SnapshotRenderer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG;IAChE;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,gBAAgB,GAAI,+CAIvB,qBAAqB,4CAevB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
* @returns A promise that resolves to the ID of the snapshot. The snapshot should be released when no longer needed.
|
|
6
6
|
*/
|
|
7
7
|
export declare function captureSnapshot(componentOrHandle: null | number | React.Component<any, any> | React.ComponentClass<any>): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Captures a snapshot of the entire screen.
|
|
10
|
+
*
|
|
11
|
+
* @returns A promise that resolves to the ID of the snapshot. The snapshot should be released when no longer needed.
|
|
12
|
+
*/
|
|
13
|
+
export declare function snapshotScreen(): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Duplicates a snapshot. The duplicate is independent and must be released separately.
|
|
16
|
+
*
|
|
17
|
+
* @param snapshotID The ID of the snapshot to duplicate.
|
|
18
|
+
* @returns A promise that resolves to the ID of the duplicated snapshot.
|
|
19
|
+
*/
|
|
20
|
+
export declare function duplicateSnapshot(snapshotID: string): Promise<string>;
|
|
8
21
|
/**
|
|
9
22
|
* Releases a snapshot.
|
|
10
23
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,iBAAiB,EACb,IAAI,GACJ,MAAM,GACN,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,GACzB,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;AAED,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azzapp/react-native-snapshot-view",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Snapshot view for react-native",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"ios",
|
|
15
15
|
"cpp",
|
|
16
16
|
"*.podspec",
|
|
17
|
+
"react-native.config.js",
|
|
17
18
|
"!ios/build",
|
|
18
19
|
"!android/build",
|
|
19
20
|
"!android/gradle",
|
|
@@ -26,13 +27,13 @@
|
|
|
26
27
|
"!**/.*"
|
|
27
28
|
],
|
|
28
29
|
"scripts": {
|
|
29
|
-
"example": "yarn workspace
|
|
30
|
+
"example": "yarn workspace react-native-snapshot-view-example",
|
|
30
31
|
"test": "jest",
|
|
31
32
|
"typecheck": "tsc",
|
|
32
33
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
33
34
|
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
34
35
|
"prepare": "bob build",
|
|
35
|
-
"release": "release-it"
|
|
36
|
+
"release": "release-it --only-version"
|
|
36
37
|
},
|
|
37
38
|
"keywords": [
|
|
38
39
|
"react-native",
|
|
@@ -54,29 +55,30 @@
|
|
|
54
55
|
"access": "public"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
|
-
"@commitlint/config-conventional": "^
|
|
58
|
-
"@
|
|
59
|
-
"@
|
|
60
|
-
"@
|
|
61
|
-
"@
|
|
62
|
-
"@
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
58
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
59
|
+
"@eslint/compat": "^1.3.2",
|
|
60
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
61
|
+
"@eslint/js": "^9.35.0",
|
|
62
|
+
"@evilmartians/lefthook": "^1.12.3",
|
|
63
|
+
"@react-native-community/cli": "20.0.1",
|
|
64
|
+
"@react-native/babel-preset": "0.81.1",
|
|
65
|
+
"@react-native/eslint-config": "^0.81.1",
|
|
66
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
67
|
+
"@types/jest": "^29.5.14",
|
|
68
|
+
"@types/react": "^19.1.0",
|
|
69
|
+
"commitlint": "^19.8.1",
|
|
70
|
+
"del-cli": "^6.0.0",
|
|
71
|
+
"eslint": "^9.35.0",
|
|
72
|
+
"eslint-config-prettier": "^10.1.8",
|
|
73
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
68
74
|
"jest": "^29.7.0",
|
|
69
|
-
"prettier": "^3.
|
|
70
|
-
"react": "
|
|
71
|
-
"react-native": "0.
|
|
72
|
-
"react-native-builder-bob": "^0.
|
|
73
|
-
"release-it": "^
|
|
74
|
-
"turbo": "^
|
|
75
|
-
"typescript": "^5.
|
|
76
|
-
},
|
|
77
|
-
"resolutions": {
|
|
78
|
-
"@types/react": "^18.2.44",
|
|
79
|
-
"react-native-builder-bob@^0.30.2": "patch:react-native-builder-bob@npm%3A0.30.2#./.yarn/patches/react-native-builder-bob-npm-0.30.2-5e6e62dece.patch"
|
|
75
|
+
"prettier": "^3.6.2",
|
|
76
|
+
"react": "19.1.0",
|
|
77
|
+
"react-native": "0.81.1",
|
|
78
|
+
"react-native-builder-bob": "^0.40.13",
|
|
79
|
+
"release-it": "^19.0.4",
|
|
80
|
+
"turbo": "^2.5.6",
|
|
81
|
+
"typescript": "^5.9.2"
|
|
80
82
|
},
|
|
81
83
|
"peerDependencies": {
|
|
82
84
|
"react": "*",
|
|
@@ -115,30 +117,6 @@
|
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
},
|
|
118
|
-
"eslintConfig": {
|
|
119
|
-
"root": true,
|
|
120
|
-
"extends": [
|
|
121
|
-
"@react-native",
|
|
122
|
-
"prettier"
|
|
123
|
-
],
|
|
124
|
-
"rules": {
|
|
125
|
-
"react/react-in-jsx-scope": "off",
|
|
126
|
-
"prettier/prettier": [
|
|
127
|
-
"error",
|
|
128
|
-
{
|
|
129
|
-
"quoteProps": "consistent",
|
|
130
|
-
"singleQuote": true,
|
|
131
|
-
"tabWidth": 2,
|
|
132
|
-
"trailingComma": "es5",
|
|
133
|
-
"useTabs": false
|
|
134
|
-
}
|
|
135
|
-
]
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
"eslintIgnore": [
|
|
139
|
-
"node_modules/",
|
|
140
|
-
"lib/"
|
|
141
|
-
],
|
|
142
120
|
"prettier": {
|
|
143
121
|
"quoteProps": "consistent",
|
|
144
122
|
"singleQuote": true,
|
|
@@ -150,8 +128,12 @@
|
|
|
150
128
|
"source": "src",
|
|
151
129
|
"output": "lib",
|
|
152
130
|
"targets": [
|
|
153
|
-
|
|
154
|
-
|
|
131
|
+
[
|
|
132
|
+
"module",
|
|
133
|
+
{
|
|
134
|
+
"esm": true
|
|
135
|
+
}
|
|
136
|
+
],
|
|
155
137
|
[
|
|
156
138
|
"typescript",
|
|
157
139
|
{
|
|
@@ -166,10 +148,16 @@
|
|
|
166
148
|
"jsSrcsDir": "src",
|
|
167
149
|
"android": {
|
|
168
150
|
"javaPackageName": "com.azzapp.rnsnapshotview"
|
|
151
|
+
},
|
|
152
|
+
"ios": {
|
|
153
|
+
"componentProvider": {
|
|
154
|
+
"RNSnapshotRenderer": "RNSnapshotRenderer"
|
|
155
|
+
}
|
|
169
156
|
}
|
|
170
157
|
},
|
|
171
158
|
"create-react-native-library": {
|
|
172
|
-
"
|
|
173
|
-
"
|
|
159
|
+
"languages": "kotlin-objc",
|
|
160
|
+
"type": "fabric-view",
|
|
161
|
+
"version": "0.54.3"
|
|
174
162
|
}
|
|
175
163
|
}
|
|
@@ -3,6 +3,8 @@ import { TurboModuleRegistry } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
export interface Spec extends TurboModule {
|
|
5
5
|
captureSnapshot(target: number): Promise<string>;
|
|
6
|
+
snapshotScreen(): Promise<string>;
|
|
7
|
+
duplicateSnapshot(snapshotID: string): Promise<string>;
|
|
6
8
|
releaseSnapshot(a: string): Promise<void>;
|
|
7
9
|
}
|
|
8
10
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import codegenNativeComponent from 'react-native
|
|
2
|
-
import type { ViewProps } from 'react-native';
|
|
1
|
+
import { codegenNativeComponent, type ViewProps } from 'react-native';
|
|
3
2
|
|
|
4
3
|
interface NativeProps extends ViewProps {
|
|
5
4
|
snapshotID?: string | null;
|
package/src/SnapshotRenderer.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import type { ViewProps } from 'react-native';
|
|
3
3
|
import RNSnapshotRenderer from './RNSnapshotRendererNativeComponent';
|
|
4
4
|
import { releaseSnapshot } from '.';
|
|
5
5
|
|
|
@@ -19,10 +19,11 @@ export type SnapshotRendererProps = Omit<ViewProps, 'children'> & {
|
|
|
19
19
|
/**
|
|
20
20
|
* A view that renders a snapshot of a view.
|
|
21
21
|
*/
|
|
22
|
-
const SnapshotRenderer = (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const SnapshotRenderer = ({
|
|
23
|
+
snapshotID,
|
|
24
|
+
autoReleaseSnapshot = true,
|
|
25
|
+
...props
|
|
26
|
+
}: SnapshotRendererProps) => {
|
|
26
27
|
const autoReleaseSnapshotRef = useRef(autoReleaseSnapshot);
|
|
27
28
|
useEffect(() => {
|
|
28
29
|
autoReleaseSnapshotRef.current = autoReleaseSnapshot;
|
|
@@ -36,9 +37,7 @@ const SnapshotRenderer = (
|
|
|
36
37
|
},
|
|
37
38
|
[snapshotID]
|
|
38
39
|
);
|
|
39
|
-
return
|
|
40
|
-
<RNSnapshotRenderer ref={forwardedRef} snapshotID={snapshotID} {...props} />
|
|
41
|
-
);
|
|
40
|
+
return <RNSnapshotRenderer snapshotID={snapshotID} {...props} />;
|
|
42
41
|
};
|
|
43
42
|
|
|
44
|
-
export default
|
|
43
|
+
export default SnapshotRenderer;
|
package/src/index.tsx
CHANGED
|
@@ -1,28 +1,5 @@
|
|
|
1
|
-
import { findNodeHandle
|
|
2
|
-
|
|
3
|
-
const LINKING_ERROR =
|
|
4
|
-
`The package '@azzapp/react-native-snapshot-view' doesn't seem to be linked. Make sure: \n\n` +
|
|
5
|
-
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
6
|
-
'- You rebuilt the app after installing the package\n' +
|
|
7
|
-
'- You are not using Expo Go\n';
|
|
8
|
-
|
|
9
|
-
// @ts-expect-error
|
|
10
|
-
const isTurboModuleEnabled = global.__turboModuleProxy != null;
|
|
11
|
-
|
|
12
|
-
const RNSnapshotViewModule = isTurboModuleEnabled
|
|
13
|
-
? require('./NativeRNSnapshotView').default
|
|
14
|
-
: NativeModules.RNSnapshotView;
|
|
15
|
-
|
|
16
|
-
const RNSnapshotView = RNSnapshotViewModule
|
|
17
|
-
? RNSnapshotViewModule
|
|
18
|
-
: new Proxy(
|
|
19
|
-
{},
|
|
20
|
-
{
|
|
21
|
-
get() {
|
|
22
|
-
throw new Error(LINKING_ERROR);
|
|
23
|
-
},
|
|
24
|
-
}
|
|
25
|
-
);
|
|
1
|
+
import { findNodeHandle } from 'react-native';
|
|
2
|
+
import RNSnapshotView from './NativeRNSnapshotView';
|
|
26
3
|
|
|
27
4
|
/**
|
|
28
5
|
* Captures a snapshot of a view. The snapshot can be rendered using the `SnapshotRenderer` component.
|
|
@@ -44,6 +21,25 @@ export function captureSnapshot(
|
|
|
44
21
|
return RNSnapshotView.captureSnapshot(handle);
|
|
45
22
|
}
|
|
46
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Captures a snapshot of the entire screen.
|
|
26
|
+
*
|
|
27
|
+
* @returns A promise that resolves to the ID of the snapshot. The snapshot should be released when no longer needed.
|
|
28
|
+
*/
|
|
29
|
+
export function snapshotScreen(): Promise<string> {
|
|
30
|
+
return RNSnapshotView.snapshotScreen();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Duplicates a snapshot. The duplicate is independent and must be released separately.
|
|
35
|
+
*
|
|
36
|
+
* @param snapshotID The ID of the snapshot to duplicate.
|
|
37
|
+
* @returns A promise that resolves to the ID of the duplicated snapshot.
|
|
38
|
+
*/
|
|
39
|
+
export function duplicateSnapshot(snapshotID: string): Promise<string> {
|
|
40
|
+
return RNSnapshotView.duplicateSnapshot(snapshotID);
|
|
41
|
+
}
|
|
42
|
+
|
|
47
43
|
/**
|
|
48
44
|
* Releases a snapshot.
|
|
49
45
|
*
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
package com.azzapp.rnsnapshotview
|
|
2
|
-
|
|
3
|
-
import android.view.View
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
-
import com.facebook.react.uimanager.SimpleViewManager
|
|
7
|
-
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
8
|
-
import com.facebook.react.viewmanagers.RNSnapshotRendererManagerDelegate
|
|
9
|
-
import com.facebook.react.viewmanagers.RNSnapshotRendererManagerInterface
|
|
10
|
-
|
|
11
|
-
abstract class RNSnapshotRendererManagerSpec<T : View> : SimpleViewManager<T>(), RNSnapshotRendererManagerInterface<T> {
|
|
12
|
-
private val mDelegate: ViewManagerDelegate<T>
|
|
13
|
-
|
|
14
|
-
init {
|
|
15
|
-
mDelegate = RNSnapshotRendererManagerDelegate(this)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
override fun getDelegate(): ViewManagerDelegate<T>? {
|
|
19
|
-
return mDelegate
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
package com.azzapp.rnsnapshotview
|
|
2
|
-
|
|
3
|
-
import android.view.View
|
|
4
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
-
import com.facebook.react.uimanager.SimpleViewManager
|
|
6
|
-
|
|
7
|
-
abstract class RNSnapshotRendererManagerSpec<T : View> : SimpleViewManager<T>() {
|
|
8
|
-
abstract fun setSnapshotID(view: T?, snapshodID: String?)
|
|
9
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
package com.azzapp.rnsnapshotview
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
-
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
5
|
-
import com.facebook.react.bridge.Promise
|
|
6
|
-
|
|
7
|
-
abstract class RNSnapshotViewSpec internal constructor(context: ReactApplicationContext) :
|
|
8
|
-
ReactContextBaseJavaModule(context) {
|
|
9
|
-
|
|
10
|
-
abstract fun captureSnapshot(viewTag: Double, promise: Promise)
|
|
11
|
-
abstract fun releaseSnapshot(snapshotID: String, promise: Promise)
|
|
12
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
#ifndef RCT_NEW_ARCH_ENABLED
|
|
2
|
-
#import <React/RCTViewManager.h>
|
|
3
|
-
#import <React/RCTUIManager.h>
|
|
4
|
-
#import "RCTBridge.h"
|
|
5
|
-
#import "Utils.h"
|
|
6
|
-
#import "RNSnapshotView.h"
|
|
7
|
-
|
|
8
|
-
@interface RNSnapshotRendererManager : RCTViewManager
|
|
9
|
-
@end
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@interface RNSnapshotRenderer : UIView
|
|
13
|
-
|
|
14
|
-
@property (nonatomic, strong) NSString *snapshotID;
|
|
15
|
-
|
|
16
|
-
@end
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@implementation RNSnapshotRenderer
|
|
20
|
-
|
|
21
|
-
{
|
|
22
|
-
UIView *_snapshotView;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-(void)setSnapshotID:(NSString *)snapshotID {
|
|
27
|
-
if (![snapshotID isEqualToString:_snapshotID]) {
|
|
28
|
-
_snapshotID = snapshotID;
|
|
29
|
-
if(_snapshotView) {
|
|
30
|
-
[_snapshotView removeFromSuperview];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
NSDictionary<NSString *, UIView *> *snapshotMap = [RNSnapshotView getSnapShotMap];
|
|
34
|
-
_snapshotView = snapshotMap[snapshotID];
|
|
35
|
-
if (_snapshotView != nil) {
|
|
36
|
-
self.autoresizesSubviews = YES;
|
|
37
|
-
_snapshotView.frame = self.bounds;
|
|
38
|
-
_snapshotView.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
|
|
39
|
-
UIViewAutoresizingFlexibleHeight);
|
|
40
|
-
|
|
41
|
-
[self addSubview:_snapshotView];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@implementation RNSnapshotRendererManager
|
|
50
|
-
|
|
51
|
-
RCT_EXPORT_MODULE(RNSnapshotRenderer)
|
|
52
|
-
|
|
53
|
-
- (UIView *)view
|
|
54
|
-
{
|
|
55
|
-
return [[RNSnapshotRenderer alloc] init];
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
RCT_EXPORT_VIEW_PROPERTY(snapshotID, NSString *)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@end
|
|
62
|
-
#endif
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["codegenNativeComponent"],"sourceRoot":"../../src","sources":["RNSnapshotRendererNativeComponent.ts"],"mappings":";;AAAA,OAAOA,sBAAsB,MAAM,yDAAyD;AAO5F,eAAeA,sBAAsB,CAAc,oBAAoB,CAAC","ignoreList":[]}
|