react-native-inapp-inspector 2.5.1 → 2.5.3
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.ar.md +151 -53
- package/README.de.md +150 -52
- package/README.es.md +139 -42
- package/README.fr.md +151 -53
- package/README.hi.md +141 -43
- package/README.ja.md +150 -69
- package/README.ko.md +153 -55
- package/README.md +73 -14
- package/README.pt-BR.md +152 -54
- package/README.ru.md +153 -55
- package/README.zh-CN.md +95 -219
- package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/results.bin +1 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/BuildConfig.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/InAppInspectorFloatingView$iconView$1.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/InAppInspectorFloatingView.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NativeNetworkInspectorSpec.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$Companion.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$activityEventListener$1.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$frameCallback$1.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$getCapturedMedia$lambda$57$$inlined$sortedByDescending$1.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$shakeListener$1.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$startVideoRecording$2$1.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorPackage.dex +0 -0
- package/android/build/.transforms/ad628164ecef2a7cc593f0fd2f4050ce/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
- package/android/build/.transforms/c93e459e24d856bde563ebb048265732/results.bin +1 -0
- package/android/build/.transforms/c93e459e24d856bde563ebb048265732/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/generated/source/buildConfig/debug/com/inappinspector/BuildConfig.java +10 -0
- package/android/build/generated/source/codegen/java/com/inappinspector/NativeNetworkInspectorSpec.java +160 -0
- package/android/build/generated/source/codegen/jni/CMakeLists.txt +28 -0
- package/android/build/generated/source/codegen/jni/RNInAppInspectorSpec-generated.cpp +212 -0
- package/android/build/generated/source/codegen/jni/RNInAppInspectorSpec.h +31 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ComponentDescriptors.cpp +22 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ComponentDescriptors.h +24 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/EventEmitters.cpp +16 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/EventEmitters.h +17 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/Props.cpp +19 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/Props.h +18 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/RNInAppInspectorSpecJSI.h +300 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ShadowNodes.cpp +17 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ShadowNodes.h +23 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/States.cpp +16 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/States.h +20 -0
- package/android/build/generated/source/codegen/schema.json +1 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +7 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
- package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-inapp-inspector_debug.kotlin_module +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/inappinspector/BuildConfig.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/inappinspector/NativeNetworkInspectorSpec.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +2 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +7 -0
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +7 -0
- package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/react-native-inapp-inspector_debug.kotlin_module +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/BuildConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/InAppInspectorFloatingView$iconView$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/InAppInspectorFloatingView.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NativeNetworkInspectorSpec.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$activityEventListener$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$frameCallback$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$getCapturedMedia$lambda$57$$inlined$sortedByDescending$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$shakeListener$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$startVideoRecording$2$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +1 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +17 -0
- package/android/build/reports/problems/problems-report.html +659 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/react-native-inapp-inspector_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/InAppInspectorFloatingView$iconView$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/InAppInspectorFloatingView.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$activityEventListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$frameCallback$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$getCapturedMedia$lambda$57$$inlined$sortedByDescending$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$shakeListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$startVideoRecording$2$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorPackage.class +0 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +154 -9
- package/dist/commonjs/capture.d.ts +5 -2
- package/dist/commonjs/capture.js +1 -1
- package/dist/commonjs/components/CountryFlag.d.ts +10 -0
- package/dist/commonjs/components/CountryFlag.js +140 -0
- package/dist/commonjs/components/EmptyState.js +6 -6
- package/dist/commonjs/components/Inspector/DeviceInfoTab.js +36 -36
- package/dist/commonjs/components/Inspector/FabLauncher.js +12 -12
- package/dist/commonjs/components/Inspector/FloatingCaptureWidget.js +23 -23
- package/dist/commonjs/components/Inspector/GlobalCrashScreenModal.js +24 -24
- package/dist/commonjs/components/Inspector/InspectorHeader.js +40 -42
- package/dist/commonjs/components/Inspector/LanguageSelectorModal.js +23 -18
- package/dist/commonjs/components/Inspector/MainScreen.js +17 -17
- package/dist/commonjs/components/Inspector/MediaGalleryTab.js +52 -34
- package/dist/commonjs/components/Inspector/MediaPreviewModal.d.ts +20 -18
- package/dist/commonjs/components/Inspector/MediaPreviewModal.js +742 -304
- package/dist/commonjs/components/Inspector/NetworkFilterModal.js +21 -21
- package/dist/commonjs/components/Inspector/SecondaryTelemetryStrip.js +6 -6
- package/dist/commonjs/components/Inspector/SocketFilterModal.js +12 -12
- package/dist/commonjs/components/Inspector/TabBar.js +3 -3
- package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +2 -2
- package/dist/commonjs/components/MetaAccordion.js +17 -17
- package/dist/commonjs/components/ModuleErrorBoundary.js +4 -4
- package/dist/commonjs/components/NetworkIcons.d.ts +19 -0
- package/dist/commonjs/components/NetworkIcons.js +87 -3
- package/dist/commonjs/components/SourcePageCard.js +9 -9
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/i18n/locales/ar.json +1 -1
- package/dist/commonjs/i18n/locales/bn.json +1 -1
- package/dist/commonjs/i18n/locales/de.json +1 -1
- package/dist/commonjs/i18n/locales/en.json +1 -1
- package/dist/commonjs/i18n/locales/es.json +1 -1
- package/dist/commonjs/i18n/locales/fr.json +1 -1
- package/dist/commonjs/i18n/locales/gu.json +1 -1
- package/dist/commonjs/i18n/locales/hi.json +1 -1
- package/dist/commonjs/i18n/locales/id.json +1 -1
- package/dist/commonjs/i18n/locales/it.json +1 -1
- package/dist/commonjs/i18n/locales/ja.json +1 -1
- package/dist/commonjs/i18n/locales/kn.json +1 -1
- package/dist/commonjs/i18n/locales/ko.json +1 -1
- package/dist/commonjs/i18n/locales/ml.json +1 -1
- package/dist/commonjs/i18n/locales/mr.json +1 -1
- package/dist/commonjs/i18n/locales/nl.json +1 -1
- package/dist/commonjs/i18n/locales/pa.json +1 -1
- package/dist/commonjs/i18n/locales/pl.json +1 -1
- package/dist/commonjs/i18n/locales/pt.json +1 -1
- package/dist/commonjs/i18n/locales/ru.json +1 -1
- package/dist/commonjs/i18n/locales/ta.json +1 -1
- package/dist/commonjs/i18n/locales/te.json +1 -1
- package/dist/commonjs/i18n/locales/tr.json +1 -1
- package/dist/commonjs/i18n/locales/vi.json +1 -1
- package/dist/commonjs/i18n/locales/zh.json +1 -1
- package/dist/commonjs/index.js +1 -1
- package/dist/commonjs/native/NativeInspector.d.ts +4 -0
- package/dist/commonjs/native/NativeInspector.js +1 -1
- package/dist/commonjs/native/NativeNetworkInspector.d.ts +1 -0
- package/dist/commonjs/styles/AppColors.d.ts +76 -0
- package/dist/commonjs/styles/AppColors.js +1 -1
- package/dist/commonjs/types/interfaces.d.ts +2 -0
- package/dist/esm/capture.d.ts +5 -2
- package/dist/esm/capture.js +1 -1
- package/dist/esm/components/CountryFlag.d.ts +10 -0
- package/dist/esm/components/CountryFlag.js +140 -0
- package/dist/esm/components/EmptyState.js +13 -13
- package/dist/esm/components/Inspector/DeviceInfoTab.js +176 -176
- package/dist/esm/components/Inspector/FabLauncher.js +37 -37
- package/dist/esm/components/Inspector/FloatingCaptureWidget.js +27 -27
- package/dist/esm/components/Inspector/GlobalCrashScreenModal.js +9 -9
- package/dist/esm/components/Inspector/InspectorHeader.js +43 -45
- package/dist/esm/components/Inspector/LanguageSelectorModal.js +107 -102
- package/dist/esm/components/Inspector/MainScreen.js +52 -52
- package/dist/esm/components/Inspector/MediaGalleryTab.js +100 -82
- package/dist/esm/components/Inspector/MediaPreviewModal.d.ts +20 -18
- package/dist/esm/components/Inspector/MediaPreviewModal.js +764 -326
- package/dist/esm/components/Inspector/NetworkFilterModal.js +37 -37
- package/dist/esm/components/Inspector/SecondaryTelemetryStrip.js +20 -20
- package/dist/esm/components/Inspector/SocketFilterModal.js +32 -32
- package/dist/esm/components/Inspector/TabBar.js +12 -12
- package/dist/esm/components/Inspector/UpdateAvailableModal.js +11 -11
- package/dist/esm/components/MetaAccordion.js +24 -24
- package/dist/esm/components/ModuleErrorBoundary.js +20 -20
- package/dist/esm/components/NetworkIcons.d.ts +19 -0
- package/dist/esm/components/NetworkIcons.js +89 -5
- package/dist/esm/components/SourcePageCard.js +21 -21
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/i18n/locales/ar.json +1 -1
- package/dist/esm/i18n/locales/bn.json +1 -1
- package/dist/esm/i18n/locales/de.json +1 -1
- package/dist/esm/i18n/locales/en.json +1 -1
- package/dist/esm/i18n/locales/es.json +1 -1
- package/dist/esm/i18n/locales/fr.json +1 -1
- package/dist/esm/i18n/locales/gu.json +1 -1
- package/dist/esm/i18n/locales/hi.json +1 -1
- package/dist/esm/i18n/locales/id.json +1 -1
- package/dist/esm/i18n/locales/it.json +1 -1
- package/dist/esm/i18n/locales/ja.json +1 -1
- package/dist/esm/i18n/locales/kn.json +1 -1
- package/dist/esm/i18n/locales/ko.json +1 -1
- package/dist/esm/i18n/locales/ml.json +1 -1
- package/dist/esm/i18n/locales/mr.json +1 -1
- package/dist/esm/i18n/locales/nl.json +1 -1
- package/dist/esm/i18n/locales/pa.json +1 -1
- package/dist/esm/i18n/locales/pl.json +1 -1
- package/dist/esm/i18n/locales/pt.json +1 -1
- package/dist/esm/i18n/locales/ru.json +1 -1
- package/dist/esm/i18n/locales/ta.json +1 -1
- package/dist/esm/i18n/locales/te.json +1 -1
- package/dist/esm/i18n/locales/tr.json +1 -1
- package/dist/esm/i18n/locales/vi.json +1 -1
- package/dist/esm/i18n/locales/zh.json +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/native/NativeInspector.d.ts +4 -0
- package/dist/esm/native/NativeInspector.js +1 -1
- package/dist/esm/native/NativeNetworkInspector.d.ts +1 -0
- package/dist/esm/styles/AppColors.d.ts +76 -0
- package/dist/esm/styles/AppColors.js +1 -1
- package/dist/esm/types/interfaces.d.ts +2 -0
- package/ios/NetworkInspectorModule.mm +487 -224
- package/package.json +1 -1
- package/react-native-inapp-inspector.podspec +1 -1
- package/src/native/NativeInspector.ts +22 -0
- package/src/native/NativeNetworkInspector.ts +1 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#import <execinfo.h>
|
|
3
3
|
#import <signal.h>
|
|
4
4
|
#import <objc/runtime.h>
|
|
5
|
+
#import <objc/message.h>
|
|
5
6
|
#import <unistd.h>
|
|
6
7
|
#import <ReplayKit/ReplayKit.h>
|
|
7
8
|
#import <AVFoundation/AVFoundation.h>
|
|
@@ -481,6 +482,144 @@ static void NativeExceptionHandler(NSException *exception) {
|
|
|
481
482
|
|
|
482
483
|
@end
|
|
483
484
|
|
|
485
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
486
|
+
// NATIVE CAMERA ROLL / PHOTO & VIDEO PICKER DELEGATE
|
|
487
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
488
|
+
|
|
489
|
+
@interface InAppInspectorPickerDelegate : NSObject <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
|
|
490
|
+
@property (nonatomic, copy) RCTPromiseResolveBlock resolve;
|
|
491
|
+
@property (nonatomic, copy) RCTPromiseRejectBlock reject;
|
|
492
|
+
@property (nonatomic, copy) NSString *capturesDirectory;
|
|
493
|
+
@end
|
|
494
|
+
|
|
495
|
+
@implementation InAppInspectorPickerDelegate
|
|
496
|
+
|
|
497
|
+
- (void)picker:(id)picker didFinishPicking:(NSArray *)results {
|
|
498
|
+
[picker dismissViewControllerAnimated:YES completion:nil];
|
|
499
|
+
if (results.count == 0) {
|
|
500
|
+
if (self.resolve) self.resolve([NSNull null]);
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
id result = results.firstObject;
|
|
505
|
+
NSItemProvider *provider = [result valueForKey:@"itemProvider"];
|
|
506
|
+
long long timestamp = (long long)([[NSDate date] timeIntervalSince1970] * 1000.0);
|
|
507
|
+
NSString *randomStr = [NSString stringWithFormat:@"%04d", arc4random_uniform(10000)];
|
|
508
|
+
|
|
509
|
+
if ([provider hasItemConformingToTypeIdentifier:@"public.movie"]) {
|
|
510
|
+
[provider loadFileRepresentationForTypeIdentifier:@"public.movie" completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
|
|
511
|
+
if (error || !url) {
|
|
512
|
+
if (self.resolve) self.resolve([NSNull null]);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
NSString *ext = [url.pathExtension lowercaseString];
|
|
516
|
+
if (ext.length == 0) ext = @"mp4";
|
|
517
|
+
NSString *filename = [NSString stringWithFormat:@"rn_iai_%lld_imported_%@.%@", timestamp, randomStr, ext];
|
|
518
|
+
NSString *destPath = [self.capturesDirectory stringByAppendingPathComponent:filename];
|
|
519
|
+
|
|
520
|
+
[[NSFileManager defaultManager] removeItemAtPath:destPath error:nil];
|
|
521
|
+
[[NSFileManager defaultManager] copyItemAtURL:url toURL:[NSURL fileURLWithPath:destPath] error:nil];
|
|
522
|
+
|
|
523
|
+
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:destPath error:nil];
|
|
524
|
+
long long sizeBytes = [attrs fileSize];
|
|
525
|
+
|
|
526
|
+
NSMutableDictionary *map = [NSMutableDictionary dictionaryWithDictionary:@{
|
|
527
|
+
@"id": filename,
|
|
528
|
+
@"type": @"video",
|
|
529
|
+
@"format": ext,
|
|
530
|
+
@"uri": [NSURL fileURLWithPath:destPath].absoluteString,
|
|
531
|
+
@"filename": filename,
|
|
532
|
+
@"sizeBytes": @(sizeBytes),
|
|
533
|
+
@"timestamp": @(timestamp)
|
|
534
|
+
}];
|
|
535
|
+
|
|
536
|
+
@try {
|
|
537
|
+
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:destPath] options:nil];
|
|
538
|
+
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
|
|
539
|
+
gen.appliesPreferredTrackTransform = YES;
|
|
540
|
+
CGImageRef cgImage = [gen copyCGImageAtTime:kCMTimeZero actualTime:NULL error:nil];
|
|
541
|
+
if (cgImage) {
|
|
542
|
+
UIImage *thumbImg = [UIImage imageWithCGImage:cgImage];
|
|
543
|
+
CGImageRelease(cgImage);
|
|
544
|
+
NSData *thumbData = UIImageJPEGRepresentation(thumbImg, 0.8);
|
|
545
|
+
NSString *thumbFile = [NSString stringWithFormat:@"rn_iai_%lld_imported_%@_thumb.jpg", timestamp, randomStr];
|
|
546
|
+
NSString *thumbPath = [self.capturesDirectory stringByAppendingPathComponent:thumbFile];
|
|
547
|
+
[thumbData writeToFile:thumbPath atomically:YES];
|
|
548
|
+
map[@"thumbnailUri"] = [NSURL fileURLWithPath:thumbPath].absoluteString;
|
|
549
|
+
}
|
|
550
|
+
} @catch (id ex) {}
|
|
551
|
+
|
|
552
|
+
if (self.resolve) self.resolve(map);
|
|
553
|
+
}];
|
|
554
|
+
} else {
|
|
555
|
+
[provider loadFileRepresentationForTypeIdentifier:@"public.image" completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
|
|
556
|
+
if (url) {
|
|
557
|
+
NSString *ext = [url.pathExtension lowercaseString];
|
|
558
|
+
if (ext.length == 0) ext = @"jpg";
|
|
559
|
+
NSString *type = [ext isEqualToString:@"gif"] ? @"gif" : @"image";
|
|
560
|
+
NSString *filename = [NSString stringWithFormat:@"rn_iai_%lld_imported_%@.%@", timestamp, randomStr, ext];
|
|
561
|
+
NSString *destPath = [self.capturesDirectory stringByAppendingPathComponent:filename];
|
|
562
|
+
|
|
563
|
+
[[NSFileManager defaultManager] removeItemAtPath:destPath error:nil];
|
|
564
|
+
[[NSFileManager defaultManager] copyItemAtURL:url toURL:[NSURL fileURLWithPath:destPath] error:nil];
|
|
565
|
+
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:destPath error:nil];
|
|
566
|
+
long long sizeBytes = [attrs fileSize];
|
|
567
|
+
|
|
568
|
+
NSDictionary *map = @{
|
|
569
|
+
@"id": filename,
|
|
570
|
+
@"type": type,
|
|
571
|
+
@"format": ext,
|
|
572
|
+
@"uri": [NSURL fileURLWithPath:destPath].absoluteString,
|
|
573
|
+
@"filename": filename,
|
|
574
|
+
@"sizeBytes": @(sizeBytes),
|
|
575
|
+
@"timestamp": @(timestamp)
|
|
576
|
+
};
|
|
577
|
+
if (self.resolve) self.resolve(map);
|
|
578
|
+
} else {
|
|
579
|
+
[provider loadObjectOfClass:[UIImage class] completionHandler:^(id<NSItemProviderReading> _Nullable object, NSError * _Nullable err) {
|
|
580
|
+
if ([object isKindOfClass:[UIImage class]]) {
|
|
581
|
+
UIImage *img = (UIImage *)object;
|
|
582
|
+
NSData *data = UIImageJPEGRepresentation(img, 0.95);
|
|
583
|
+
NSString *filename = [NSString stringWithFormat:@"rn_iai_%lld_imported_%@.jpg", timestamp, randomStr];
|
|
584
|
+
NSString *destPath = [self.capturesDirectory stringByAppendingPathComponent:filename];
|
|
585
|
+
[data writeToFile:destPath atomically:YES];
|
|
586
|
+
|
|
587
|
+
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:destPath error:nil];
|
|
588
|
+
long long sizeBytes = [attrs fileSize];
|
|
589
|
+
|
|
590
|
+
NSDictionary *map = @{
|
|
591
|
+
@"id": filename,
|
|
592
|
+
@"type": @"image",
|
|
593
|
+
@"format": @"jpg",
|
|
594
|
+
@"uri": [NSURL fileURLWithPath:destPath].absoluteString,
|
|
595
|
+
@"filename": filename,
|
|
596
|
+
@"sizeBytes": @(sizeBytes),
|
|
597
|
+
@"timestamp": @(timestamp)
|
|
598
|
+
};
|
|
599
|
+
if (self.resolve) self.resolve(map);
|
|
600
|
+
} else {
|
|
601
|
+
if (self.resolve) self.resolve([NSNull null]);
|
|
602
|
+
}
|
|
603
|
+
}];
|
|
604
|
+
}
|
|
605
|
+
}];
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
|
|
610
|
+
[picker dismissViewControllerAnimated:YES completion:nil];
|
|
611
|
+
if (self.resolve) self.resolve([NSNull null]);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
|
|
615
|
+
[picker dismissViewControllerAnimated:YES completion:nil];
|
|
616
|
+
if (self.resolve) self.resolve([NSNull null]);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
@end
|
|
620
|
+
|
|
621
|
+
static InAppInspectorPickerDelegate *g_pickerDelegate = nil;
|
|
622
|
+
|
|
484
623
|
@implementation NetworkInspectorModule {
|
|
485
624
|
bool hasListeners;
|
|
486
625
|
CADisplayLink *displayLink;
|
|
@@ -1116,6 +1255,21 @@ RCT_EXPORT_METHOD(getNativeCachedPage:(NSString *)pageKey
|
|
|
1116
1255
|
return capturesDir;
|
|
1117
1256
|
}
|
|
1118
1257
|
|
|
1258
|
+
/**
|
|
1259
|
+
* Generates a filename in the format: rn_iai_{YYYYMMDD_HHmmss_SSS}_{fileType}_{random6}.{ext}
|
|
1260
|
+
*/
|
|
1261
|
+
- (NSString *)generateCaptureFilename:(NSString *)fileType ext:(NSString *)ext {
|
|
1262
|
+
NSDateFormatter *df = [[NSDateFormatter alloc] init];
|
|
1263
|
+
[df setDateFormat:@"yyyyMMdd_HHmmss_SSS"];
|
|
1264
|
+
NSString *dateStamp = [df stringFromDate:[NSDate date]];
|
|
1265
|
+
NSString *chars = @"abcdefghijklmnopqrstuvwxyz0123456789";
|
|
1266
|
+
NSMutableString *random = [NSMutableString stringWithCapacity:6];
|
|
1267
|
+
for (int i = 0; i < 6; i++) {
|
|
1268
|
+
[random appendFormat:@"%C", [chars characterAtIndex:arc4random_uniform((uint32_t)chars.length)]];
|
|
1269
|
+
}
|
|
1270
|
+
return [NSString stringWithFormat:@"rn_iai_%@_%@_%@.%@", dateStamp, fileType, random, ext];
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1119
1273
|
- (UIWindow *)findActiveKeyWindow {
|
|
1120
1274
|
UIWindow *foundWindow = nil;
|
|
1121
1275
|
if (@available(iOS 13.0, *)) {
|
|
@@ -1283,7 +1437,7 @@ RCT_EXPORT_METHOD(getNativeCachedPage:(NSString *)pageKey
|
|
|
1283
1437
|
CGSize videoSize = CGSizeMake(width, height);
|
|
1284
1438
|
long long timestamp = (long long)([[NSDate date] timeIntervalSince1970] * 1000.0);
|
|
1285
1439
|
self->_softwareRecordingTimestamp = timestamp;
|
|
1286
|
-
NSString *filename = [
|
|
1440
|
+
NSString *filename = [self generateCaptureFilename:@"video" ext:@"mp4"];
|
|
1287
1441
|
NSString *filePath = [[self getCapturesDirectory] stringByAppendingPathComponent:filename];
|
|
1288
1442
|
NSURL *outputUrl = [NSURL fileURLWithPath:filePath];
|
|
1289
1443
|
|
|
@@ -1352,7 +1506,8 @@ RCT_EXPORT_METHOD(getNativeCachedPage:(NSString *)pageKey
|
|
|
1352
1506
|
if (firstImg) {
|
|
1353
1507
|
NSData *thumbData = UIImageJPEGRepresentation(firstImg, 0.8);
|
|
1354
1508
|
if (thumbData) {
|
|
1355
|
-
NSString *
|
|
1509
|
+
NSString *thumbBaseName = [[filename stringByDeletingPathExtension] stringByReplacingOccurrencesOfString:@"_video_" withString:@"_thumb_"];
|
|
1510
|
+
NSString *thumbFilename = [NSString stringWithFormat:@"%@.jpg", thumbBaseName];
|
|
1356
1511
|
NSString *thumbFilePath = [[self getCapturesDirectory] stringByAppendingPathComponent:thumbFilename];
|
|
1357
1512
|
[thumbData writeToFile:thumbFilePath atomically:YES];
|
|
1358
1513
|
self->_softwareRecordingThumbnailPath = thumbFilePath;
|
|
@@ -1473,7 +1628,7 @@ RCT_EXPORT_METHOD(takeScreenshot:(NSDictionary *)options
|
|
|
1473
1628
|
}
|
|
1474
1629
|
|
|
1475
1630
|
long long timestamp = (long long)([[NSDate date] timeIntervalSince1970] * 1000.0);
|
|
1476
|
-
NSString *filename = [
|
|
1631
|
+
NSString *filename = [self generateCaptureFilename:@"screenshot" ext:ext];
|
|
1477
1632
|
NSString *filePath = [[self getCapturesDirectory] stringByAppendingPathComponent:filename];
|
|
1478
1633
|
|
|
1479
1634
|
[data writeToFile:filePath atomically:YES];
|
|
@@ -1571,7 +1726,7 @@ RCT_EXPORT_METHOD(stopVideoRecording:(RCTPromiseResolveBlock)resolve
|
|
|
1571
1726
|
CGImageRelease(imgRef);
|
|
1572
1727
|
NSData *tData = UIImageJPEGRepresentation(thumbImg, 0.85);
|
|
1573
1728
|
if (tData) {
|
|
1574
|
-
NSString *generatedThumbFile = [
|
|
1729
|
+
NSString *generatedThumbFile = [self generateCaptureFilename:@"thumb" ext:@"jpg"];
|
|
1575
1730
|
NSString *generatedThumbPath = [[self getCapturesDirectory] stringByAppendingPathComponent:generatedThumbFile];
|
|
1576
1731
|
[tData writeToFile:generatedThumbPath atomically:YES];
|
|
1577
1732
|
result[@"thumbnailUri"] = [NSURL fileURLWithPath:generatedThumbPath].absoluteString;
|
|
@@ -1666,7 +1821,7 @@ RCT_EXPORT_METHOD(convertToGif:(NSString *)videoUri
|
|
|
1666
1821
|
[reader startReading];
|
|
1667
1822
|
|
|
1668
1823
|
long long timestamp = (long long)([[NSDate date] timeIntervalSince1970] * 1000.0);
|
|
1669
|
-
NSString *filename = [
|
|
1824
|
+
NSString *filename = [self generateCaptureFilename:@"anim" ext:@"gif"];
|
|
1670
1825
|
NSString *filePath = [[self getCapturesDirectory] stringByAppendingPathComponent:filename];
|
|
1671
1826
|
NSURL *gifUrl = [NSURL fileURLWithPath:filePath];
|
|
1672
1827
|
|
|
@@ -1755,7 +1910,7 @@ RCT_EXPORT_METHOD(getCapturedMedia:(RCTPromiseResolveBlock)resolve
|
|
|
1755
1910
|
|
|
1756
1911
|
for (NSString *file in (files ?: @[])) {
|
|
1757
1912
|
// Skip standalone thumbnail files
|
|
1758
|
-
if ([file hasPrefix:@"thumb_"]) continue;
|
|
1913
|
+
if ([file hasPrefix:@"thumb_"] || [file containsString:@"_thumb_"]) continue;
|
|
1759
1914
|
|
|
1760
1915
|
NSString *fullPath = [dir stringByAppendingPathComponent:file];
|
|
1761
1916
|
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil];
|
|
@@ -1784,11 +1939,17 @@ RCT_EXPORT_METHOD(getCapturedMedia:(RCTPromiseResolveBlock)resolve
|
|
|
1784
1939
|
}];
|
|
1785
1940
|
|
|
1786
1941
|
if ([type isEqualToString:@"video"]) {
|
|
1787
|
-
//
|
|
1942
|
+
// Try new naming convention: replace _video_ with _thumb_ in base name
|
|
1788
1943
|
NSString *nameWithoutExt = [file stringByDeletingPathExtension];
|
|
1789
|
-
NSString *
|
|
1790
|
-
NSString *thumbFile = [NSString stringWithFormat:@"
|
|
1944
|
+
NSString *thumbBaseName = [nameWithoutExt stringByReplacingOccurrencesOfString:@"_video_" withString:@"_thumb_"];
|
|
1945
|
+
NSString *thumbFile = [NSString stringWithFormat:@"%@.jpg", thumbBaseName];
|
|
1791
1946
|
NSString *thumbFullPath = [dir stringByAppendingPathComponent:thumbFile];
|
|
1947
|
+
// Fallback: legacy naming convention (thumb_{timestamp}.jpg)
|
|
1948
|
+
if (![[NSFileManager defaultManager] fileExistsAtPath:thumbFullPath]) {
|
|
1949
|
+
NSString *timestampSuffix = [nameWithoutExt stringByReplacingOccurrencesOfString:@"video_" withString:@""];
|
|
1950
|
+
thumbFile = [NSString stringWithFormat:@"thumb_%@.jpg", timestampSuffix];
|
|
1951
|
+
thumbFullPath = [dir stringByAppendingPathComponent:thumbFile];
|
|
1952
|
+
}
|
|
1792
1953
|
if ([[NSFileManager defaultManager] fileExistsAtPath:thumbFullPath]) {
|
|
1793
1954
|
item[@"thumbnailUri"] = [NSURL fileURLWithPath:thumbFullPath].absoluteString;
|
|
1794
1955
|
} else {
|
|
@@ -1841,14 +2002,22 @@ RCT_EXPORT_METHOD(deleteCapturedMedia:(NSString *)uri
|
|
|
1841
2002
|
|
|
1842
2003
|
// Also remove any related thumbnail
|
|
1843
2004
|
NSString *filename = [path lastPathComponent];
|
|
1844
|
-
if ([filename hasPrefix:@"video_"]) {
|
|
2005
|
+
if ([filename containsString:@"_video_"] || [filename hasPrefix:@"video_"]) {
|
|
1845
2006
|
NSString *nameWithoutExt = [filename stringByDeletingPathExtension];
|
|
1846
|
-
|
|
1847
|
-
NSString *
|
|
2007
|
+
// Try new convention: replace _video_ with _thumb_
|
|
2008
|
+
NSString *thumbBaseName = [nameWithoutExt stringByReplacingOccurrencesOfString:@"_video_" withString:@"_thumb_"];
|
|
2009
|
+
NSString *thumbFile = [NSString stringWithFormat:@"%@.jpg", thumbBaseName];
|
|
1848
2010
|
NSString *thumbPath = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:thumbFile];
|
|
1849
2011
|
if ([[NSFileManager defaultManager] fileExistsAtPath:thumbPath]) {
|
|
1850
2012
|
[[NSFileManager defaultManager] removeItemAtPath:thumbPath error:nil];
|
|
1851
2013
|
}
|
|
2014
|
+
// Fallback: legacy convention
|
|
2015
|
+
NSString *timestampSuffix = [nameWithoutExt stringByReplacingOccurrencesOfString:@"video_" withString:@""];
|
|
2016
|
+
NSString *legacyThumbFile = [NSString stringWithFormat:@"thumb_%@.jpg", timestampSuffix];
|
|
2017
|
+
NSString *legacyThumbPath = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:legacyThumbFile];
|
|
2018
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:legacyThumbPath]) {
|
|
2019
|
+
[[NSFileManager defaultManager] removeItemAtPath:legacyThumbPath error:nil];
|
|
2020
|
+
}
|
|
1852
2021
|
}
|
|
1853
2022
|
|
|
1854
2023
|
resolve(@(YES));
|
|
@@ -1920,241 +2089,241 @@ RCT_EXPORT_METHOD(editPhoto:(NSDictionary *)options
|
|
|
1920
2089
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
1921
2090
|
reject:(RCTPromiseRejectBlock)reject) {
|
|
1922
2091
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
1923
|
-
@
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
NSString *cleanPath = rawUri;
|
|
1931
|
-
if ([cleanPath hasPrefix:@"file://"]) {
|
|
1932
|
-
cleanPath = [cleanPath substringFromIndex:7];
|
|
1933
|
-
}
|
|
1934
|
-
cleanPath = [cleanPath stringByRemovingPercentEncoding];
|
|
1935
|
-
|
|
1936
|
-
UIImage *sourceImage = [UIImage imageWithContentsOfFile:cleanPath];
|
|
1937
|
-
if (!sourceImage) {
|
|
1938
|
-
reject(@"IMAGE_LOAD_FAILED", @"Failed to load source image", nil);
|
|
1939
|
-
return;
|
|
1940
|
-
}
|
|
2092
|
+
@autoreleasepool {
|
|
2093
|
+
@try {
|
|
2094
|
+
NSString *rawUri = options[@"uri"];
|
|
2095
|
+
if (!rawUri || rawUri.length == 0) {
|
|
2096
|
+
reject(@"INVALID_URI", @"Image URI is missing or empty", nil);
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
1941
2099
|
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
if (!ciImage) {
|
|
1948
|
-
reject(@"CIIMAGE_FAILED", @"Failed to initialize CoreImage pipeline", nil);
|
|
1949
|
-
return;
|
|
1950
|
-
}
|
|
2100
|
+
NSString *cleanPath = rawUri;
|
|
2101
|
+
if ([cleanPath hasPrefix:@"file://"]) {
|
|
2102
|
+
cleanPath = [cleanPath substringFromIndex:7];
|
|
2103
|
+
}
|
|
2104
|
+
cleanPath = [cleanPath stringByRemovingPercentEncoding];
|
|
1951
2105
|
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
CGAffineTransform transform = CGAffineTransformIdentity;
|
|
1958
|
-
if (rotation == 90) {
|
|
1959
|
-
transform = CGAffineTransformRotate(transform, -M_PI_2);
|
|
1960
|
-
} else if (rotation == 180) {
|
|
1961
|
-
transform = CGAffineTransformRotate(transform, M_PI);
|
|
1962
|
-
} else if (rotation == 270) {
|
|
1963
|
-
transform = CGAffineTransformRotate(transform, M_PI_2);
|
|
1964
|
-
}
|
|
1965
|
-
if (flipH) {
|
|
1966
|
-
transform = CGAffineTransformScale(transform, -1, 1);
|
|
1967
|
-
}
|
|
1968
|
-
if (flipV) {
|
|
1969
|
-
transform = CGAffineTransformScale(transform, 1, -1);
|
|
1970
|
-
}
|
|
1971
|
-
if (!CGAffineTransformIsIdentity(transform)) {
|
|
1972
|
-
ciImage = [ciImage imageByApplyingTransform:transform];
|
|
1973
|
-
CGRect newExtent = ciImage.extent;
|
|
1974
|
-
CGAffineTransform fixOrigin = CGAffineTransformMakeTranslation(-newExtent.origin.x, -newExtent.origin.y);
|
|
1975
|
-
ciImage = [ciImage imageByApplyingTransform:fixOrigin];
|
|
1976
|
-
}
|
|
2106
|
+
UIImage *sourceImage = [UIImage imageWithContentsOfFile:cleanPath];
|
|
2107
|
+
if (!sourceImage) {
|
|
2108
|
+
reject(@"IMAGE_LOAD_FAILED", @"Failed to load source image", nil);
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
1977
2111
|
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
CGFloat y = [cropDict[@"y"] doubleValue];
|
|
1983
|
-
CGFloat width = [cropDict[@"width"] doubleValue];
|
|
1984
|
-
CGFloat height = [cropDict[@"height"] doubleValue];
|
|
1985
|
-
BOOL isNorm = [cropDict[@"isNormalized"] boolValue];
|
|
1986
|
-
|
|
1987
|
-
CGRect extent = ciImage.extent;
|
|
1988
|
-
if (isNorm) {
|
|
1989
|
-
x *= extent.size.width;
|
|
1990
|
-
y *= extent.size.height;
|
|
1991
|
-
width *= extent.size.width;
|
|
1992
|
-
height *= extent.size.height;
|
|
2112
|
+
// 1. Convert to CIImage
|
|
2113
|
+
CIImage *ciImage = [CIImage imageWithCGImage:sourceImage.CGImage];
|
|
2114
|
+
if (!ciImage) {
|
|
2115
|
+
ciImage = [CIImage imageWithContentsOfURL:[NSURL fileURLWithPath:cleanPath]];
|
|
1993
2116
|
}
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
CGRect intersection = CGRectIntersection(extent, cropRect);
|
|
1998
|
-
if (!CGRectIsNull(intersection) && intersection.size.width > 0 && intersection.size.height > 0) {
|
|
1999
|
-
ciImage = [ciImage imageByCroppingToRect:intersection];
|
|
2117
|
+
if (!ciImage) {
|
|
2118
|
+
reject(@"CIIMAGE_FAILED", @"Failed to initialize CoreImage pipeline", nil);
|
|
2119
|
+
return;
|
|
2000
2120
|
}
|
|
2001
|
-
}
|
|
2002
2121
|
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
if (saturation) [colorControls setValue:saturation forKey:kCIInputSaturationKey];
|
|
2016
|
-
ciImage = colorControls.outputImage ?: ciImage;
|
|
2122
|
+
// 2. Apply Rotation & Flip
|
|
2123
|
+
NSInteger rotation = [options[@"rotation"] integerValue];
|
|
2124
|
+
BOOL flipH = [options[@"flipHorizontal"] boolValue];
|
|
2125
|
+
BOOL flipV = [options[@"flipVertical"] boolValue];
|
|
2126
|
+
|
|
2127
|
+
CGAffineTransform transform = CGAffineTransformIdentity;
|
|
2128
|
+
if (rotation == 90) {
|
|
2129
|
+
transform = CGAffineTransformRotate(transform, -M_PI_2);
|
|
2130
|
+
} else if (rotation == 180) {
|
|
2131
|
+
transform = CGAffineTransformRotate(transform, M_PI);
|
|
2132
|
+
} else if (rotation == 270) {
|
|
2133
|
+
transform = CGAffineTransformRotate(transform, M_PI_2);
|
|
2017
2134
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
ciImage =
|
|
2135
|
+
if (flipH) {
|
|
2136
|
+
transform = CGAffineTransformScale(transform, -1, 1);
|
|
2137
|
+
}
|
|
2138
|
+
if (flipV) {
|
|
2139
|
+
transform = CGAffineTransformScale(transform, 1, -1);
|
|
2140
|
+
}
|
|
2141
|
+
if (!CGAffineTransformIsIdentity(transform)) {
|
|
2142
|
+
ciImage = [ciImage imageByApplyingTransform:transform];
|
|
2143
|
+
CGRect newExtent = ciImage.extent;
|
|
2144
|
+
CGAffineTransform fixOrigin = CGAffineTransformMakeTranslation(-newExtent.origin.x, -newExtent.origin.y);
|
|
2145
|
+
ciImage = [ciImage imageByApplyingTransform:fixOrigin];
|
|
2029
2146
|
}
|
|
2030
2147
|
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2148
|
+
// 3. Apply Crop
|
|
2149
|
+
NSDictionary *cropDict = options[@"crop"];
|
|
2150
|
+
if (cropDict && [cropDict isKindOfClass:[NSDictionary class]]) {
|
|
2151
|
+
CGFloat x = [cropDict[@"x"] doubleValue];
|
|
2152
|
+
CGFloat y = [cropDict[@"y"] doubleValue];
|
|
2153
|
+
CGFloat width = [cropDict[@"width"] doubleValue];
|
|
2154
|
+
CGFloat height = [cropDict[@"height"] doubleValue];
|
|
2155
|
+
BOOL isNorm = [cropDict[@"isNormalized"] boolValue];
|
|
2156
|
+
|
|
2157
|
+
CGRect extent = ciImage.extent;
|
|
2158
|
+
if (isNorm) {
|
|
2159
|
+
x *= extent.size.width;
|
|
2160
|
+
y *= extent.size.height;
|
|
2161
|
+
width *= extent.size.width;
|
|
2162
|
+
height *= extent.size.height;
|
|
2163
|
+
}
|
|
2164
|
+
// CoreImage coordinate system (bottom-left origin)
|
|
2165
|
+
CGFloat ciY = extent.size.height - (y + height);
|
|
2166
|
+
CGRect cropRect = CGRectMake(x, ciY, width, height);
|
|
2167
|
+
CGRect intersection = CGRectIntersection(extent, cropRect);
|
|
2168
|
+
if (!CGRectIsNull(intersection) && intersection.size.width > 0 && intersection.size.height > 0) {
|
|
2169
|
+
ciImage = [ciImage imageByCroppingToRect:intersection];
|
|
2170
|
+
}
|
|
2038
2171
|
}
|
|
2039
2172
|
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2173
|
+
// 4. Color Grading Adjustments (CIColorControls, CITemperatureAndTint, CIVignette)
|
|
2174
|
+
NSDictionary *adjustments = options[@"adjustments"];
|
|
2175
|
+
if (adjustments && [adjustments isKindOfClass:[NSDictionary class]]) {
|
|
2176
|
+
NSNumber *brightness = adjustments[@"brightness"];
|
|
2177
|
+
NSNumber *contrast = adjustments[@"contrast"];
|
|
2178
|
+
NSNumber *saturation = adjustments[@"saturation"];
|
|
2179
|
+
|
|
2180
|
+
if (brightness || contrast || saturation) {
|
|
2181
|
+
CIFilter *colorControls = [CIFilter filterWithName:@"CIColorControls"];
|
|
2182
|
+
[colorControls setValue:ciImage forKey:kCIInputImageKey];
|
|
2183
|
+
if (brightness) [colorControls setValue:brightness forKey:kCIInputBrightnessKey];
|
|
2184
|
+
if (contrast) [colorControls setValue:contrast forKey:kCIInputContrastKey];
|
|
2185
|
+
if (saturation) [colorControls setValue:saturation forKey:kCIInputSaturationKey];
|
|
2186
|
+
ciImage = colorControls.outputImage ?: ciImage;
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
NSNumber *temperature = adjustments[@"temperature"];
|
|
2190
|
+
if (temperature && [temperature doubleValue] != 0) {
|
|
2191
|
+
CIFilter *tempFilter = [CIFilter filterWithName:@"CITemperatureAndTint"];
|
|
2192
|
+
[tempFilter setValue:ciImage forKey:kCIInputImageKey];
|
|
2193
|
+
CIVector *neutral = [CIVector vectorWithX:6500 Y:0];
|
|
2194
|
+
CGFloat shift = [temperature doubleValue] * 2000;
|
|
2195
|
+
CIVector *target = [CIVector vectorWithX:6500 + shift Y:0];
|
|
2196
|
+
[tempFilter setValue:neutral forKey:@"inputNeutral"];
|
|
2197
|
+
[tempFilter setValue:target forKey:@"inputTargetNeutral"];
|
|
2198
|
+
ciImage = tempFilter.outputImage ?: ciImage;
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
NSNumber *vignette = adjustments[@"vignette"];
|
|
2202
|
+
if (vignette && [vignette doubleValue] > 0) {
|
|
2203
|
+
CIFilter *vigFilter = [CIFilter filterWithName:@"CIVignette"];
|
|
2204
|
+
[vigFilter setValue:ciImage forKey:kCIInputImageKey];
|
|
2205
|
+
[vigFilter setValue:@([vignette doubleValue] * 2.0) forKey:kCIInputIntensityKey];
|
|
2206
|
+
[vigFilter setValue:@(1.0) forKey:kCIInputRadiusKey];
|
|
2207
|
+
ciImage = vigFilter.outputImage ?: ciImage;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
NSNumber *sharpen = adjustments[@"sharpen"];
|
|
2211
|
+
if (sharpen && [sharpen doubleValue] > 0) {
|
|
2212
|
+
CIFilter *sharpFilter = [CIFilter filterWithName:@"CISharpenLuminance"];
|
|
2213
|
+
[sharpFilter setValue:ciImage forKey:kCIInputImageKey];
|
|
2214
|
+
[sharpFilter setValue:@([sharpen doubleValue] * 2.0) forKey:kCIInputSharpnessKey];
|
|
2215
|
+
ciImage = sharpFilter.outputImage ?: ciImage;
|
|
2216
|
+
}
|
|
2046
2217
|
}
|
|
2047
|
-
}
|
|
2048
2218
|
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2219
|
+
// 5. Preset Filters
|
|
2220
|
+
NSString *preset = options[@"filterPreset"];
|
|
2221
|
+
if (preset && preset.length > 0 && ![preset isEqualToString:@"none"]) {
|
|
2222
|
+
NSString *filterName = nil;
|
|
2223
|
+
if ([preset isEqualToString:@"mono"]) filterName = @"CIPhotoEffectMono";
|
|
2224
|
+
else if ([preset isEqualToString:@"noir"]) filterName = @"CIPhotoEffectNoir";
|
|
2225
|
+
else if ([preset isEqualToString:@"sepia"]) filterName = @"CISepiaTone";
|
|
2226
|
+
else if ([preset isEqualToString:@"vibrant"]) filterName = @"CIPhotoEffectChrome";
|
|
2227
|
+
else if ([preset isEqualToString:@"fade"]) filterName = @"CIPhotoEffectFade";
|
|
2228
|
+
else if ([preset isEqualToString:@"vintage"]) filterName = @"CIPhotoEffectInstant";
|
|
2229
|
+
|
|
2230
|
+
if (filterName) {
|
|
2231
|
+
CIFilter *pFilter = [CIFilter filterWithName:filterName];
|
|
2232
|
+
[pFilter setValue:ciImage forKey:kCIInputImageKey];
|
|
2233
|
+
ciImage = pFilter.outputImage ?: ciImage;
|
|
2234
|
+
}
|
|
2064
2235
|
}
|
|
2065
|
-
}
|
|
2066
2236
|
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2237
|
+
// 6. GPU Render to File
|
|
2238
|
+
CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer: @(NO)}];
|
|
2239
|
+
CGImageRef cgImage = [context createCGImage:ciImage fromRect:ciImage.extent];
|
|
2240
|
+
if (!cgImage) {
|
|
2241
|
+
reject(@"RENDER_FAILED", @"Failed to render CGImage", nil);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2074
2244
|
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2245
|
+
UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
|
|
2246
|
+
CGImageRelease(cgImage);
|
|
2247
|
+
|
|
2248
|
+
// 7. Apply Redactions & Annotations Overlay if provided
|
|
2249
|
+
NSArray *redactions = options[@"redactions"];
|
|
2250
|
+
NSArray *annotations = options[@"annotations"];
|
|
2251
|
+
if ((redactions && [redactions isKindOfClass:[NSArray class]] && redactions.count > 0) ||
|
|
2252
|
+
(annotations && [annotations isKindOfClass:[NSArray class]] && annotations.count > 0)) {
|
|
2253
|
+
UIGraphicsBeginImageContextWithOptions(resultImage.size, NO, 1.0);
|
|
2254
|
+
[resultImage drawInRect:CGRectMake(0, 0, resultImage.size.width, resultImage.size.height)];
|
|
2255
|
+
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
|
2256
|
+
|
|
2257
|
+
if (redactions && [redactions isKindOfClass:[NSArray class]]) {
|
|
2258
|
+
for (NSDictionary *box in redactions) {
|
|
2259
|
+
CGFloat x = [box[@"x"] doubleValue];
|
|
2260
|
+
CGFloat y = [box[@"y"] doubleValue];
|
|
2261
|
+
CGFloat w = [box[@"width"] doubleValue];
|
|
2262
|
+
CGFloat h = [box[@"height"] doubleValue];
|
|
2263
|
+
BOOL isNorm = [box[@"isNormalized"] boolValue];
|
|
2264
|
+
if (isNorm) {
|
|
2265
|
+
x *= resultImage.size.width;
|
|
2266
|
+
y *= resultImage.size.height;
|
|
2267
|
+
w *= resultImage.size.width;
|
|
2268
|
+
h *= resultImage.size.height;
|
|
2269
|
+
}
|
|
2270
|
+
CGContextSetFillColorWithColor(ctx, [UIColor blackColor].CGColor);
|
|
2271
|
+
CGContextFillRect(ctx, CGRectMake(x, y, w, h));
|
|
2099
2272
|
}
|
|
2100
|
-
CGContextSetFillColorWithColor(ctx, [UIColor blackColor].CGColor);
|
|
2101
|
-
CGContextFillRect(ctx, CGRectMake(x, y, w, h));
|
|
2102
2273
|
}
|
|
2103
|
-
}
|
|
2104
2274
|
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2275
|
+
if (annotations && [annotations isKindOfClass:[NSArray class]]) {
|
|
2276
|
+
for (NSDictionary *ann in annotations) {
|
|
2277
|
+
CGFloat x = [ann[@"x"] doubleValue];
|
|
2278
|
+
CGFloat y = [ann[@"y"] doubleValue];
|
|
2279
|
+
CGFloat w = [ann[@"width"] doubleValue];
|
|
2280
|
+
CGFloat h = [ann[@"height"] doubleValue];
|
|
2281
|
+
BOOL isNorm = [ann[@"isNormalized"] boolValue];
|
|
2282
|
+
if (isNorm) {
|
|
2283
|
+
x *= resultImage.size.width;
|
|
2284
|
+
y *= resultImage.size.height;
|
|
2285
|
+
w *= resultImage.size.width;
|
|
2286
|
+
h *= resultImage.size.height;
|
|
2287
|
+
}
|
|
2288
|
+
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
|
|
2289
|
+
CGContextSetLineWidth(ctx, 4.0);
|
|
2290
|
+
CGContextStrokeRect(ctx, CGRectMake(x, y, w, h));
|
|
2117
2291
|
}
|
|
2118
|
-
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
|
|
2119
|
-
CGContextSetLineWidth(ctx, 4.0);
|
|
2120
|
-
CGContextStrokeRect(ctx, CGRectMake(x, y, w, h));
|
|
2121
2292
|
}
|
|
2293
|
+
|
|
2294
|
+
resultImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
2295
|
+
UIGraphicsEndImageContext();
|
|
2122
2296
|
}
|
|
2123
2297
|
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2298
|
+
NSString *format = [options[@"format"] lowercaseString] ?: @"jpeg";
|
|
2299
|
+
CGFloat quality = options[@"quality"] ? [options[@"quality"] doubleValue] : 0.9;
|
|
2300
|
+
NSData *imageData = nil;
|
|
2301
|
+
NSString *ext = @"jpg";
|
|
2302
|
+
NSString *mime = @"image/jpeg";
|
|
2127
2303
|
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2304
|
+
if ([format isEqualToString:@"png"]) {
|
|
2305
|
+
imageData = UIImagePNGRepresentation(resultImage);
|
|
2306
|
+
ext = @"png";
|
|
2307
|
+
mime = @"image/png";
|
|
2308
|
+
} else {
|
|
2309
|
+
imageData = UIImageJPEGRepresentation(resultImage, quality);
|
|
2310
|
+
}
|
|
2133
2311
|
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2312
|
+
NSString *fileName = [self generateCaptureFilename:@"edit" ext:ext];
|
|
2313
|
+
NSString *outPath = [[self getCapturesDirectory] stringByAppendingPathComponent:fileName];
|
|
2314
|
+
[imageData writeToFile:outPath atomically:YES];
|
|
2315
|
+
|
|
2316
|
+
resolve(@{
|
|
2317
|
+
@"uri": [NSURL fileURLWithPath:outPath].absoluteString,
|
|
2318
|
+
@"width": @(resultImage.size.width),
|
|
2319
|
+
@"height": @(resultImage.size.height),
|
|
2320
|
+
@"size": @(imageData.length),
|
|
2321
|
+
@"mimeType": mime,
|
|
2322
|
+
@"format": format,
|
|
2323
|
+
});
|
|
2324
|
+
} @catch (NSException *ex) {
|
|
2325
|
+
reject(@"EDIT_FAILED", ex.reason ?: @"Photo edit failed", nil);
|
|
2140
2326
|
}
|
|
2141
|
-
|
|
2142
|
-
NSDateFormatter *df = [[NSDateFormatter alloc] init];
|
|
2143
|
-
[df setDateFormat:@"yyyyMMdd_HHmmss_SSS"];
|
|
2144
|
-
NSString *fileName = [NSString stringWithFormat:@"edit_%@.%@", [df stringFromDate:[NSDate date]], ext];
|
|
2145
|
-
NSString *outPath = [[self getCapturesDirectory] stringByAppendingPathComponent:fileName];
|
|
2146
|
-
[imageData writeToFile:outPath atomically:YES];
|
|
2147
|
-
|
|
2148
|
-
resolve(@{
|
|
2149
|
-
@"uri": [NSURL fileURLWithPath:outPath].absoluteString,
|
|
2150
|
-
@"width": @(resultImage.size.width),
|
|
2151
|
-
@"height": @(resultImage.size.height),
|
|
2152
|
-
@"size": @(imageData.length),
|
|
2153
|
-
@"mimeType": mime,
|
|
2154
|
-
@"format": format,
|
|
2155
|
-
});
|
|
2156
|
-
} @catch (NSException *ex) {
|
|
2157
|
-
reject(@"EDIT_FAILED", ex.reason ?: @"Photo edit failed", nil);
|
|
2158
2327
|
}
|
|
2159
2328
|
});
|
|
2160
2329
|
}
|
|
@@ -2235,9 +2404,7 @@ RCT_EXPORT_METHOD(trimVideo:(NSDictionary *)options
|
|
|
2235
2404
|
else if ([quality isEqualToString:@"low"]) preset = AVAssetExportPreset640x480;
|
|
2236
2405
|
|
|
2237
2406
|
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:preset];
|
|
2238
|
-
|
|
2239
|
-
[df setDateFormat:@"yyyyMMdd_HHmmss_SSS"];
|
|
2240
|
-
NSString *fileName = [NSString stringWithFormat:@"trim_%@.mp4", [df stringFromDate:[NSDate date]]];
|
|
2407
|
+
NSString *fileName = [self generateCaptureFilename:@"trim" ext:@"mp4"];
|
|
2241
2408
|
NSString *outPath = [[self getCapturesDirectory] stringByAppendingPathComponent:fileName];
|
|
2242
2409
|
NSURL *outUrl = [NSURL fileURLWithPath:outPath];
|
|
2243
2410
|
|
|
@@ -2340,6 +2507,102 @@ RCT_EXPORT_METHOD(generateFilmstrip:(NSDictionary *)options
|
|
|
2340
2507
|
});
|
|
2341
2508
|
}
|
|
2342
2509
|
|
|
2510
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2511
|
+
// NATIVE CAMERA ROLL / PHOTO & VIDEO PICKER
|
|
2512
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2513
|
+
|
|
2514
|
+
RCT_EXPORT_METHOD(pickMedia:(NSDictionary *)options
|
|
2515
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
2516
|
+
reject:(RCTPromiseRejectBlock)reject) {
|
|
2517
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
2518
|
+
NSString *mediaType = options[@"mediaType"] ?: @"any";
|
|
2519
|
+
|
|
2520
|
+
UIWindow *keyWin = nil;
|
|
2521
|
+
if (@available(iOS 13.0, *)) {
|
|
2522
|
+
for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
|
2523
|
+
if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) {
|
|
2524
|
+
for (UIWindow *w in ((UIWindowScene *)scene).windows) {
|
|
2525
|
+
if (w.isKeyWindow) {
|
|
2526
|
+
keyWin = w;
|
|
2527
|
+
break;
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
if (keyWin) break;
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
if (!keyWin) {
|
|
2535
|
+
#pragma clang diagnostic push
|
|
2536
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
2537
|
+
keyWin = [UIApplication sharedApplication].keyWindow ?: [UIApplication sharedApplication].windows.firstObject;
|
|
2538
|
+
#pragma clang diagnostic pop
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
UIViewController *rootVC = keyWin.rootViewController;
|
|
2542
|
+
while (rootVC.presentedViewController) {
|
|
2543
|
+
rootVC = rootVC.presentedViewController;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
g_pickerDelegate = [[InAppInspectorPickerDelegate alloc] init];
|
|
2547
|
+
g_pickerDelegate.resolve = resolve;
|
|
2548
|
+
g_pickerDelegate.reject = reject;
|
|
2549
|
+
g_pickerDelegate.capturesDirectory = [self getCapturesDirectory];
|
|
2550
|
+
|
|
2551
|
+
Class PHPickerVCClass = NSClassFromString(@"PHPickerViewController");
|
|
2552
|
+
Class PHPickerConfigClass = NSClassFromString(@"PHPickerConfiguration");
|
|
2553
|
+
Class PHPickerFilterClass = NSClassFromString(@"PHPickerFilter");
|
|
2554
|
+
|
|
2555
|
+
if (PHPickerVCClass && PHPickerConfigClass && PHPickerFilterClass) {
|
|
2556
|
+
id config = [[PHPickerConfigClass alloc] init];
|
|
2557
|
+
[config setValue:@1 forKey:@"selectionLimit"];
|
|
2558
|
+
|
|
2559
|
+
id filter = nil;
|
|
2560
|
+
SEL imgFilterSel = NSSelectorFromString(@"imagesFilter");
|
|
2561
|
+
SEL vidFilterSel = NSSelectorFromString(@"videosFilter");
|
|
2562
|
+
SEL anyFilterSel = NSSelectorFromString(@"anyFilterMatchingSubfilters:");
|
|
2563
|
+
|
|
2564
|
+
if ([mediaType isEqualToString:@"image"]) {
|
|
2565
|
+
if ([PHPickerFilterClass respondsToSelector:imgFilterSel]) {
|
|
2566
|
+
filter = ((id (*)(id, SEL))objc_msgSend)(PHPickerFilterClass, imgFilterSel);
|
|
2567
|
+
}
|
|
2568
|
+
} else if ([mediaType isEqualToString:@"video"]) {
|
|
2569
|
+
if ([PHPickerFilterClass respondsToSelector:vidFilterSel]) {
|
|
2570
|
+
filter = ((id (*)(id, SEL))objc_msgSend)(PHPickerFilterClass, vidFilterSel);
|
|
2571
|
+
}
|
|
2572
|
+
} else {
|
|
2573
|
+
id imgFilter = [PHPickerFilterClass respondsToSelector:imgFilterSel] ? ((id (*)(id, SEL))objc_msgSend)(PHPickerFilterClass, imgFilterSel) : nil;
|
|
2574
|
+
id vidFilter = [PHPickerFilterClass respondsToSelector:vidFilterSel] ? ((id (*)(id, SEL))objc_msgSend)(PHPickerFilterClass, vidFilterSel) : nil;
|
|
2575
|
+
if (imgFilter && vidFilter && [PHPickerFilterClass respondsToSelector:anyFilterSel]) {
|
|
2576
|
+
filter = ((id (*)(id, SEL, id))objc_msgSend)(PHPickerFilterClass, anyFilterSel, @[imgFilter, vidFilter]);
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
if (filter) {
|
|
2580
|
+
[config setValue:filter forKey:@"filter"];
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
SEL initConfigSel = NSSelectorFromString(@"initWithConfiguration:");
|
|
2584
|
+
id rawPicker = [PHPickerVCClass alloc];
|
|
2585
|
+
UIViewController *picker = ((UIViewController * (*)(id, SEL, id))objc_msgSend)(rawPicker, initConfigSel, config);
|
|
2586
|
+
[picker setValue:g_pickerDelegate forKey:@"delegate"];
|
|
2587
|
+
[rootVC presentViewController:picker animated:YES completion:nil];
|
|
2588
|
+
} else {
|
|
2589
|
+
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
|
2590
|
+
picker.delegate = g_pickerDelegate;
|
|
2591
|
+
#pragma clang diagnostic push
|
|
2592
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
2593
|
+
if ([mediaType isEqualToString:@"image"]) {
|
|
2594
|
+
picker.mediaTypes = @[(NSString *)kUTTypeImage];
|
|
2595
|
+
} else if ([mediaType isEqualToString:@"video"]) {
|
|
2596
|
+
picker.mediaTypes = @[(NSString *)kUTTypeMovie];
|
|
2597
|
+
} else {
|
|
2598
|
+
picker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
|
|
2599
|
+
}
|
|
2600
|
+
#pragma clang diagnostic pop
|
|
2601
|
+
[rootVC presentViewController:picker animated:YES completion:nil];
|
|
2602
|
+
}
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2343
2606
|
|
|
2344
2607
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2345
2608
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|