expo-paste-input 0.1.8 → 0.1.10
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/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/results.bin +1 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/pasteinput/BuildConfig.dex +0 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/pasteinput/ExpoPasteInputModule$definition$lambda$1$$inlined$View$1.dex +0 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/pasteinput/ExpoPasteInputModule.dex +0 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/pasteinput/ExpoPasteInputView$1.dex +0 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/pasteinput/ExpoPasteInputView$ClipboardPayload.dex +0 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/pasteinput/ExpoPasteInputView$createActionModeCallback$1.dex +0 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/pasteinput/ExpoPasteInputView.dex +0 -0
- package/android/build/.transforms/04cfbef6d6438014a0f56f30321e9943/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
- package/android/build/.transforms/61052c0b101cc72f1be04cd5637e14e3/results.bin +1 -0
- package/android/build/.transforms/61052c0b101cc72f1be04cd5637e14e3/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/generated/source/buildConfig/debug/expo/modules/pasteinput/BuildConfig.java +10 -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/mergeDebugAssets/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/java_res/debug/processDebugJavaRes/out/META-INF/expo-paste-input_debug.kotlin_module +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/expo/modules/pasteinput/BuildConfig.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/expo-paste-input_debug.kotlin_module +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/pasteinput/BuildConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/pasteinput/ExpoPasteInputModule$definition$lambda$1$$inlined$View$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/pasteinput/ExpoPasteInputModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/pasteinput/ExpoPasteInputView$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/pasteinput/ExpoPasteInputView$ClipboardPayload.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/pasteinput/ExpoPasteInputView$createActionModeCallback$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/pasteinput/ExpoPasteInputView.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/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 +14 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/expo-paste-input_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputModule$definition$lambda$1$$inlined$View$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputView$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputView$ClipboardPayload.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputView$createActionModeCallback$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputView.class +0 -0
- package/android/src/main/java/expo/modules/pasteinput/ExpoPasteInputView.kt +204 -135
- package/ios/ExpoPasteInputView.swift +35 -13
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
o/bundleLibRuntimeToDirDebug
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
o/classes
|
|
Binary file
|
package/android/build/generated/source/buildConfig/debug/expo/modules/pasteinput/BuildConfig.java
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Automatically generated file. DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
package expo.modules.pasteinput;
|
|
5
|
+
|
|
6
|
+
public final class BuildConfig {
|
|
7
|
+
public static final boolean DEBUG = Boolean.parseBoolean("true");
|
|
8
|
+
public static final String LIBRARY_PACKAGE_NAME = "expo.modules.pasteinput";
|
|
9
|
+
public static final String BUILD_TYPE = "debug";
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"artifactType": {
|
|
4
|
+
"type": "AAPT_FRIENDLY_MERGED_MANIFESTS",
|
|
5
|
+
"kind": "Directory"
|
|
6
|
+
},
|
|
7
|
+
"applicationId": "expo.modules.pasteinput",
|
|
8
|
+
"variantName": "debug",
|
|
9
|
+
"elements": [
|
|
10
|
+
{
|
|
11
|
+
"type": "SINGLE",
|
|
12
|
+
"filters": [],
|
|
13
|
+
"attributes": [],
|
|
14
|
+
"outputFile": "AndroidManifest.xml"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"elementType": "File"
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#Sun Mar 29 01:33:17 IST 2026
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/build/generated/res/resValues/debug"/></dataSet><mergedItems/></merger>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/assets"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/debug/assets"/></dataSet><dataSet config="generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/build/intermediates/shader_assets/debug/compileDebugShaders/out"/></dataSet></merger>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/debug/jniLibs"/></dataSet></merger>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/debug/shaders"/></dataSet></merger>
|
|
Binary file
|
|
Binary file
|
package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0 Warning/Error
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
expo.modules.pasteinput
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i
ADDED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len
ADDED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i
ADDED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len
ADDED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin
ADDED
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- Merging decision tree log ---
|
|
2
|
+
manifest
|
|
3
|
+
ADDED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml:1:1-2:12
|
|
4
|
+
INJECTED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml:1:1-2:12
|
|
5
|
+
package
|
|
6
|
+
INJECTED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml
|
|
7
|
+
uses-sdk
|
|
8
|
+
INJECTED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml reason: use-sdk injection requested
|
|
9
|
+
INJECTED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml
|
|
10
|
+
INJECTED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml
|
|
11
|
+
android:targetSdkVersion
|
|
12
|
+
INJECTED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml
|
|
13
|
+
android:minSdkVersion
|
|
14
|
+
INJECTED from /Users/arunabhverma/React_Native/expo/my_lib/expo-paste-input/android/src/main/AndroidManifest.xml
|
|
Binary file
|
|
Binary file
|
package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputModule.class
ADDED
|
Binary file
|
package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputView$1.class
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/tmp/kotlin-classes/debug/expo/modules/pasteinput/ExpoPasteInputView.class
ADDED
|
Binary file
|
|
@@ -6,6 +6,7 @@ import android.graphics.Bitmap
|
|
|
6
6
|
import android.graphics.BitmapFactory
|
|
7
7
|
import android.net.Uri
|
|
8
8
|
import android.os.Build
|
|
9
|
+
import android.os.SystemClock
|
|
9
10
|
import android.view.View
|
|
10
11
|
import android.view.ViewGroup
|
|
11
12
|
import android.view.ActionMode
|
|
@@ -18,16 +19,26 @@ import expo.modules.kotlin.viewevent.EventDispatcher
|
|
|
18
19
|
import expo.modules.kotlin.views.ExpoView
|
|
19
20
|
import java.io.File
|
|
20
21
|
import java.io.FileOutputStream
|
|
21
|
-
import java.io.InputStream
|
|
22
|
-
import java.io.IOException
|
|
23
22
|
|
|
24
23
|
class ExpoPasteInputView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
|
|
25
24
|
private val onPaste by EventDispatcher()
|
|
26
25
|
private var textInputView: EditText? = null
|
|
27
26
|
private var isMonitoring: Boolean = false
|
|
28
27
|
private var contentListener: OnReceiveContentListener? = null
|
|
29
|
-
private var
|
|
30
|
-
private var
|
|
28
|
+
private var originalSelectionActionModeCallback: ActionMode.Callback? = null
|
|
29
|
+
private var originalInsertionActionModeCallback: ActionMode.Callback? = null
|
|
30
|
+
private var customSelectionActionModeCallback: ActionMode.Callback? = null
|
|
31
|
+
private var customInsertionActionModeCallback: ActionMode.Callback? = null
|
|
32
|
+
private var suppressOnReceiveContentUntilMs: Long = 0L
|
|
33
|
+
|
|
34
|
+
private data class ClipboardPayload(
|
|
35
|
+
val imageUris: List<Uri>,
|
|
36
|
+
val gifUris: List<Uri>,
|
|
37
|
+
val textContent: String?
|
|
38
|
+
) {
|
|
39
|
+
val hasImages: Boolean
|
|
40
|
+
get() = imageUris.isNotEmpty() || gifUris.isNotEmpty()
|
|
41
|
+
}
|
|
31
42
|
|
|
32
43
|
init {
|
|
33
44
|
// Make view completely transparent and non-interactive - only monitor paste events
|
|
@@ -102,8 +113,10 @@ class ExpoPasteInputView(context: Context, appContext: AppContext) : ExpoView(co
|
|
|
102
113
|
isMonitoring = false
|
|
103
114
|
textInputView = null
|
|
104
115
|
contentListener = null
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
originalSelectionActionModeCallback = null
|
|
117
|
+
originalInsertionActionModeCallback = null
|
|
118
|
+
customSelectionActionModeCallback = null
|
|
119
|
+
customInsertionActionModeCallback = null
|
|
107
120
|
}
|
|
108
121
|
|
|
109
122
|
private fun setupPasteHandling(editText: EditText) {
|
|
@@ -129,66 +142,33 @@ class ExpoPasteInputView(context: Context, appContext: AppContext) : ExpoView(co
|
|
|
129
142
|
}
|
|
130
143
|
|
|
131
144
|
// Restore original ActionMode.Callback
|
|
132
|
-
if (
|
|
133
|
-
editText.customSelectionActionModeCallback =
|
|
145
|
+
if (customSelectionActionModeCallback != null) {
|
|
146
|
+
editText.customSelectionActionModeCallback = originalSelectionActionModeCallback
|
|
147
|
+
}
|
|
148
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && customInsertionActionModeCallback != null) {
|
|
149
|
+
editText.customInsertionActionModeCallback = originalInsertionActionModeCallback
|
|
134
150
|
}
|
|
135
151
|
}
|
|
136
152
|
|
|
137
153
|
private fun createContentListener(): OnReceiveContentListener {
|
|
138
|
-
return OnReceiveContentListener {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (itemCount == 0) {
|
|
143
|
-
return@OnReceiveContentListener payload
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Collect images and GIFs separately
|
|
147
|
-
val imageUris = mutableListOf<Uri>()
|
|
148
|
-
val gifUris = mutableListOf<Uri>()
|
|
149
|
-
var textContent: String? = null
|
|
150
|
-
|
|
151
|
-
// Process each item in the clip
|
|
152
|
-
for (i in 0 until itemCount) {
|
|
153
|
-
val item = clip.getItemAt(i)
|
|
154
|
-
|
|
155
|
-
// Check for image URI
|
|
156
|
-
val uri = item.uri
|
|
157
|
-
if (uri != null) {
|
|
158
|
-
val mimeType = context.contentResolver.getType(uri)
|
|
159
|
-
if (mimeType != null && mimeType.startsWith("image/")) {
|
|
160
|
-
// Separate GIFs from regular images
|
|
161
|
-
if (mimeType == "image/gif") {
|
|
162
|
-
gifUris.add(uri)
|
|
163
|
-
} else {
|
|
164
|
-
imageUris.add(uri)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Check for text
|
|
170
|
-
val text = item.text
|
|
171
|
-
if (!text.isNullOrEmpty() && textContent == null) {
|
|
172
|
-
textContent = text.toString()
|
|
173
|
-
}
|
|
154
|
+
return OnReceiveContentListener { _, payload ->
|
|
155
|
+
if (shouldSuppressOnReceiveContent()) {
|
|
156
|
+
return@OnReceiveContentListener null
|
|
174
157
|
}
|
|
175
158
|
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
processMultipleImagePaste(imageUris, gifUris)
|
|
179
|
-
//
|
|
180
|
-
// This prevents Android from showing the "Can't add images" toast
|
|
159
|
+
val parsed = parseClipboardPayload(payload.clip, context)
|
|
160
|
+
if (parsed.hasImages) {
|
|
161
|
+
processMultipleImagePaste(parsed.imageUris, parsed.gifUris)
|
|
162
|
+
// Consume image content to prevent default EditText "can't paste image" UX.
|
|
181
163
|
return@OnReceiveContentListener null
|
|
182
164
|
}
|
|
183
165
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// Allow default text paste behavior
|
|
166
|
+
if (!parsed.textContent.isNullOrEmpty()) {
|
|
167
|
+
handleTextPaste(parsed.textContent)
|
|
168
|
+
// Keep native text insertion behavior.
|
|
188
169
|
return@OnReceiveContentListener payload
|
|
189
170
|
}
|
|
190
171
|
|
|
191
|
-
// Unsupported content type
|
|
192
172
|
handleUnsupportedPaste()
|
|
193
173
|
return@OnReceiveContentListener payload
|
|
194
174
|
}
|
|
@@ -198,107 +178,190 @@ class ExpoPasteInputView(context: Context, appContext: AppContext) : ExpoView(co
|
|
|
198
178
|
// Intercept paste from context menu to prevent toast
|
|
199
179
|
// This must happen BEFORE Android tries to paste, otherwise the toast appears
|
|
200
180
|
try {
|
|
201
|
-
// Store original
|
|
202
|
-
|
|
181
|
+
// Store original callbacks if they exist
|
|
182
|
+
originalSelectionActionModeCallback = editText.customSelectionActionModeCallback
|
|
183
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
184
|
+
originalInsertionActionModeCallback = editText.customInsertionActionModeCallback
|
|
185
|
+
}
|
|
203
186
|
|
|
204
|
-
// Set up
|
|
205
|
-
|
|
206
|
-
|
|
187
|
+
// Set up custom callbacks to intercept paste from both selection and insertion menus.
|
|
188
|
+
customSelectionActionModeCallback = createActionModeCallback(
|
|
189
|
+
editText = editText,
|
|
190
|
+
originalCallback = originalSelectionActionModeCallback
|
|
191
|
+
)
|
|
192
|
+
editText.customSelectionActionModeCallback = customSelectionActionModeCallback
|
|
193
|
+
|
|
194
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
195
|
+
customInsertionActionModeCallback = createActionModeCallback(
|
|
196
|
+
editText = editText,
|
|
197
|
+
originalCallback = originalInsertionActionModeCallback
|
|
198
|
+
)
|
|
199
|
+
editText.customInsertionActionModeCallback = customInsertionActionModeCallback
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
} catch (e: Exception) {
|
|
203
|
+
// If ActionMode.Callback approach fails, we'll rely on OnReceiveContentListener
|
|
204
|
+
// which should still work but may show the toast briefly
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private fun createActionModeCallback(
|
|
209
|
+
editText: EditText,
|
|
210
|
+
originalCallback: ActionMode.Callback?
|
|
211
|
+
): ActionMode.Callback {
|
|
212
|
+
return object : ActionMode.Callback {
|
|
207
213
|
override fun onCreateActionMode(mode: ActionMode?, menu: android.view.Menu?): Boolean {
|
|
208
214
|
// Delegate to original callback if it exists
|
|
209
|
-
return
|
|
215
|
+
return originalCallback?.onCreateActionMode(mode, menu) ?: true
|
|
210
216
|
}
|
|
211
217
|
|
|
212
218
|
override fun onPrepareActionMode(mode: ActionMode?, menu: android.view.Menu?): Boolean {
|
|
213
219
|
// Delegate to original callback if it exists
|
|
214
|
-
return
|
|
220
|
+
return originalCallback?.onPrepareActionMode(mode, menu) ?: false
|
|
215
221
|
}
|
|
216
222
|
|
|
217
223
|
override fun onActionItemClicked(mode: ActionMode?, item: android.view.MenuItem?): Boolean {
|
|
218
224
|
if (item?.itemId == android.R.id.paste) {
|
|
219
|
-
|
|
220
|
-
val clipboard = editText.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
221
|
-
val clipData = clipboard.primaryClip
|
|
222
|
-
|
|
223
|
-
if (clipData != null && clipData.itemCount > 0) {
|
|
224
|
-
// Collect images and GIFs separately
|
|
225
|
-
val imageUris = mutableListOf<Uri>()
|
|
226
|
-
val gifUris = mutableListOf<Uri>()
|
|
227
|
-
var textContent: String? = null
|
|
228
|
-
|
|
229
|
-
// Process all items in the clipboard
|
|
230
|
-
for (i in 0 until clipData.itemCount) {
|
|
231
|
-
val clipItem = clipData.getItemAt(i)
|
|
232
|
-
val uri = clipItem.uri
|
|
233
|
-
|
|
234
|
-
// Check if it's an image
|
|
235
|
-
if (uri != null) {
|
|
236
|
-
val mimeType = editText.context.contentResolver.getType(uri)
|
|
237
|
-
if (mimeType != null && mimeType.startsWith("image/")) {
|
|
238
|
-
// Separate GIFs from regular images
|
|
239
|
-
if (mimeType == "image/gif") {
|
|
240
|
-
gifUris.add(uri)
|
|
241
|
-
} else {
|
|
242
|
-
imageUris.add(uri)
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Check for text (only take first text item)
|
|
248
|
-
if (textContent == null) {
|
|
249
|
-
val text = clipItem.text
|
|
250
|
-
if (!text.isNullOrEmpty()) {
|
|
251
|
-
textContent = text.toString()
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Handle GIFs and images (always as array, even for single item)
|
|
257
|
-
if (gifUris.isNotEmpty() || imageUris.isNotEmpty()) {
|
|
258
|
-
processMultipleImagePaste(imageUris, gifUris)
|
|
259
|
-
mode?.finish()
|
|
260
|
-
return true // We handled it, prevent default paste
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Check for text
|
|
264
|
-
if (textContent != null) {
|
|
265
|
-
// For text, let the normal paste logic run, then notify JS
|
|
266
|
-
var handled = false
|
|
267
|
-
|
|
268
|
-
// 1) Let any existing callback handle it
|
|
269
|
-
if (originalActionModeCallback != null) {
|
|
270
|
-
handled = originalActionModeCallback!!.onActionItemClicked(mode, item)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// 2) If nothing handled it, fall back to EditText's default handler
|
|
274
|
-
if (!handled && item != null) {
|
|
275
|
-
handled = editText.onTextContextMenuItem(item.itemId)
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (handled) {
|
|
279
|
-
handleTextPaste(textContent)
|
|
280
|
-
}
|
|
281
|
-
mode?.finish()
|
|
282
|
-
return handled
|
|
283
|
-
}
|
|
284
|
-
}
|
|
225
|
+
return handlePasteFromActionMode(editText, mode, item, originalCallback)
|
|
285
226
|
}
|
|
286
227
|
|
|
287
228
|
// For other actions, delegate to original callback or return false
|
|
288
|
-
return
|
|
229
|
+
return originalCallback?.onActionItemClicked(mode, item) ?: false
|
|
289
230
|
}
|
|
290
231
|
|
|
291
232
|
override fun onDestroyActionMode(mode: ActionMode?) {
|
|
292
233
|
// Delegate to original callback if it exists
|
|
293
|
-
|
|
234
|
+
originalCallback?.onDestroyActionMode(mode)
|
|
294
235
|
}
|
|
295
236
|
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private fun handlePasteFromActionMode(
|
|
240
|
+
editText: EditText,
|
|
241
|
+
mode: ActionMode?,
|
|
242
|
+
item: android.view.MenuItem,
|
|
243
|
+
originalCallback: ActionMode.Callback?
|
|
244
|
+
): Boolean {
|
|
245
|
+
val clipboard = editText.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
246
|
+
val parsed = parseClipboardPayload(clipboard.primaryClip, editText.context)
|
|
247
|
+
|
|
248
|
+
if (parsed.hasImages) {
|
|
249
|
+
markSuppressOnReceiveContent()
|
|
250
|
+
processMultipleImagePaste(parsed.imageUris, parsed.gifUris)
|
|
251
|
+
mode?.finish()
|
|
252
|
+
return true
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
val text = parsed.textContent
|
|
256
|
+
if (!text.isNullOrEmpty()) {
|
|
257
|
+
var handled = originalCallback?.onActionItemClicked(mode, item) ?: false
|
|
258
|
+
if (!handled) {
|
|
259
|
+
handled = editText.onTextContextMenuItem(item.itemId)
|
|
260
|
+
}
|
|
261
|
+
if (!handled) {
|
|
262
|
+
insertTextAtCursor(editText, text)
|
|
263
|
+
handled = true
|
|
264
|
+
}
|
|
296
265
|
|
|
297
|
-
|
|
266
|
+
if (handled) {
|
|
267
|
+
// On Android < 12, ActionMode path is the only reliable callback for text.
|
|
268
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
|
269
|
+
handleTextPaste(text)
|
|
270
|
+
}
|
|
271
|
+
markSuppressOnReceiveContent()
|
|
272
|
+
mode?.finish()
|
|
273
|
+
return true
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
handleUnsupportedPaste()
|
|
278
|
+
mode?.finish()
|
|
279
|
+
return true
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
private fun parseClipboardPayload(
|
|
283
|
+
clipData: android.content.ClipData?,
|
|
284
|
+
sourceContext: Context
|
|
285
|
+
): ClipboardPayload {
|
|
286
|
+
if (clipData == null || clipData.itemCount <= 0) {
|
|
287
|
+
return ClipboardPayload(emptyList(), emptyList(), null)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
val imageUris = mutableListOf<Uri>()
|
|
291
|
+
val gifUris = mutableListOf<Uri>()
|
|
292
|
+
var textContent: String? = null
|
|
293
|
+
|
|
294
|
+
for (i in 0 until clipData.itemCount) {
|
|
295
|
+
val clipItem = clipData.getItemAt(i)
|
|
296
|
+
val uri = clipItem.uri
|
|
297
|
+
if (uri != null) {
|
|
298
|
+
val mimeType = sourceContext.contentResolver.getType(uri)?.lowercase()
|
|
299
|
+
if (mimeType != null && mimeType.startsWith("image/")) {
|
|
300
|
+
if (mimeType == "image/gif") {
|
|
301
|
+
gifUris.add(uri)
|
|
302
|
+
} else {
|
|
303
|
+
imageUris.add(uri)
|
|
304
|
+
}
|
|
305
|
+
} else if (isLikelyGifUri(uri)) {
|
|
306
|
+
gifUris.add(uri)
|
|
307
|
+
} else if (isLikelyImageUri(uri)) {
|
|
308
|
+
imageUris.add(uri)
|
|
309
|
+
}
|
|
310
|
+
}
|
|
298
311
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
312
|
+
if (textContent == null) {
|
|
313
|
+
val text = clipItem.coerceToText(sourceContext)
|
|
314
|
+
if (!text.isNullOrEmpty()) {
|
|
315
|
+
textContent = text.toString()
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return ClipboardPayload(
|
|
321
|
+
imageUris = imageUris,
|
|
322
|
+
gifUris = gifUris,
|
|
323
|
+
textContent = textContent
|
|
324
|
+
)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private fun isLikelyImageUri(uri: Uri): Boolean {
|
|
328
|
+
val fileName = uri.lastPathSegment?.lowercase() ?: return false
|
|
329
|
+
return fileName.endsWith(".png") ||
|
|
330
|
+
fileName.endsWith(".jpg") ||
|
|
331
|
+
fileName.endsWith(".jpeg") ||
|
|
332
|
+
fileName.endsWith(".webp") ||
|
|
333
|
+
fileName.endsWith(".heic") ||
|
|
334
|
+
fileName.endsWith(".heif")
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private fun isLikelyGifUri(uri: Uri): Boolean {
|
|
338
|
+
val fileName = uri.lastPathSegment?.lowercase() ?: return false
|
|
339
|
+
return fileName.endsWith(".gif")
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
private fun markSuppressOnReceiveContent() {
|
|
343
|
+
suppressOnReceiveContentUntilMs = SystemClock.elapsedRealtime() + 500L
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
private fun shouldSuppressOnReceiveContent(): Boolean {
|
|
347
|
+
return SystemClock.elapsedRealtime() <= suppressOnReceiveContentUntilMs
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
private fun insertTextAtCursor(editText: EditText, text: String) {
|
|
351
|
+
val editable = editText.editableText ?: return
|
|
352
|
+
val start = editText.selectionStart
|
|
353
|
+
val end = editText.selectionEnd
|
|
354
|
+
|
|
355
|
+
val replaceStart = minOf(start, end).coerceAtLeast(0)
|
|
356
|
+
val replaceEnd = maxOf(start, end).coerceAtLeast(0)
|
|
357
|
+
|
|
358
|
+
if (replaceStart <= replaceEnd && replaceEnd <= editable.length) {
|
|
359
|
+
editable.replace(replaceStart, replaceEnd, text)
|
|
360
|
+
val newCursor = (replaceStart + text.length).coerceAtMost(editable.length)
|
|
361
|
+
editText.setSelection(newCursor)
|
|
362
|
+
} else {
|
|
363
|
+
editable.append(text)
|
|
364
|
+
editText.setSelection(editable.length)
|
|
302
365
|
}
|
|
303
366
|
}
|
|
304
367
|
|
|
@@ -351,12 +414,18 @@ class ExpoPasteInputView(context: Context, appContext: AppContext) : ExpoView(co
|
|
|
351
414
|
|
|
352
415
|
// Save to cache directory
|
|
353
416
|
val cacheDir = context.cacheDir
|
|
417
|
+
val usePng = bitmap.hasAlpha()
|
|
418
|
+
val fileExtension = if (usePng) "png" else "jpg"
|
|
354
419
|
// Use UUID-like approach for better uniqueness: timestamp + counter
|
|
355
|
-
val fileName = "${System.currentTimeMillis()}_${filePaths.size}
|
|
420
|
+
val fileName = "${System.currentTimeMillis()}_${filePaths.size}.$fileExtension"
|
|
356
421
|
val file = File(cacheDir, fileName)
|
|
357
422
|
|
|
358
423
|
FileOutputStream(file).use { outputStream ->
|
|
359
|
-
|
|
424
|
+
if (usePng) {
|
|
425
|
+
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
|
|
426
|
+
} else {
|
|
427
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream)
|
|
428
|
+
}
|
|
360
429
|
outputStream.flush()
|
|
361
430
|
}
|
|
362
431
|
|
|
@@ -27,6 +27,8 @@ class ExpoPasteInputView: ExpoView {
|
|
|
27
27
|
private let onPaste = EventDispatcher()
|
|
28
28
|
private var textInputView: UIView?
|
|
29
29
|
private var isMonitoring: Bool = false
|
|
30
|
+
private let gifTypes: Set<String> = ["com.compuserve.gif", "public.gif", "image/gif"]
|
|
31
|
+
private let webpTypes: Set<String> = ["org.webmproject.webp", "public.webp", "image/webp"]
|
|
30
32
|
// Track which classes have been swizzled (once per class, never unswizzle)
|
|
31
33
|
private static var swizzledClasses: Set<String> = []
|
|
32
34
|
|
|
@@ -146,13 +148,15 @@ class ExpoPasteInputView: ExpoView {
|
|
|
146
148
|
let swizzledImplementation: @convention(block) (AnyObject, Selector, Any?) -> Bool = { object, action, sender in
|
|
147
149
|
// Check if this text input is associated with a wrapper
|
|
148
150
|
if let weakWrapper = objc_getAssociatedObject(object, &textInputWrapperKey) as? WeakWrapper,
|
|
149
|
-
weakWrapper.value
|
|
151
|
+
let wrapper = weakWrapper.value {
|
|
150
152
|
// Only process if this is our wrapped text input
|
|
151
153
|
if action == #selector(UIResponderStandardEditActions.paste(_:)) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
// IMPORTANT:
|
|
155
|
+
// Do not read UIPasteboard content here. iOS may show the
|
|
156
|
+
// "App would like to paste" privacy prompt on menu-open checks.
|
|
157
|
+
// We allow paste action visibility and read the pasteboard only
|
|
158
|
+
// when the user explicitly taps Paste in `paste(_:)`.
|
|
159
|
+
return true
|
|
156
160
|
}
|
|
157
161
|
}
|
|
158
162
|
|
|
@@ -203,9 +207,8 @@ class ExpoPasteInputView: ExpoView {
|
|
|
203
207
|
|
|
204
208
|
// CRITICAL: Check for GIFs FIRST using explicit type queries
|
|
205
209
|
// This gets raw data without triggering UIImage conversion
|
|
206
|
-
let gifTypes = ["com.compuserve.gif", "public.gif", "image/gif"]
|
|
207
210
|
var hasGIF = false
|
|
208
|
-
for gifType in gifTypes {
|
|
211
|
+
for gifType in wrapper.gifTypes {
|
|
209
212
|
if let gifData = pasteboard.data(forPasteboardType: gifType), !gifData.isEmpty {
|
|
210
213
|
hasGIF = true
|
|
211
214
|
break
|
|
@@ -216,7 +219,7 @@ class ExpoPasteInputView: ExpoView {
|
|
|
216
219
|
if !hasGIF {
|
|
217
220
|
for item in pasteboard.items {
|
|
218
221
|
for (key, _) in item {
|
|
219
|
-
if gifTypes.contains(key) || key.lowercased().contains("gif") {
|
|
222
|
+
if wrapper.gifTypes.contains(key) || key.lowercased().contains("gif") {
|
|
220
223
|
hasGIF = true
|
|
221
224
|
break
|
|
222
225
|
}
|
|
@@ -243,8 +246,9 @@ class ExpoPasteInputView: ExpoView {
|
|
|
243
246
|
}
|
|
244
247
|
|
|
245
248
|
// Check if this looks like image data
|
|
246
|
-
let isImageKey = key.contains("image") || key.contains("png") || key.contains("jpeg") ||
|
|
247
|
-
|
|
249
|
+
let isImageKey = key.contains("image") || key.contains("png") || key.contains("jpeg") ||
|
|
250
|
+
key.contains("jpg") || key.contains("tiff") || key.contains("heic") ||
|
|
251
|
+
key.contains("heif") || key.contains("webp")
|
|
248
252
|
|
|
249
253
|
if isImageKey && (value is Data || value is UIImage) {
|
|
250
254
|
hasImageData = true
|
|
@@ -267,7 +271,7 @@ class ExpoPasteInputView: ExpoView {
|
|
|
267
271
|
|
|
268
272
|
// Fallback: check hasImages only if no image data found in items
|
|
269
273
|
// This is safer as we've already checked for GIFs above
|
|
270
|
-
if pasteboard.hasImages {
|
|
274
|
+
if pasteboard.hasImages || wrapper.hasPasteboardData(forAnyTypeIn: wrapper.webpTypes, pasteboard: pasteboard) {
|
|
271
275
|
DispatchQueue.main.async {
|
|
272
276
|
wrapper.processPasteboardContent()
|
|
273
277
|
}
|
|
@@ -326,8 +330,17 @@ class ExpoPasteInputView: ExpoView {
|
|
|
326
330
|
// This method is only called for image pastes
|
|
327
331
|
let pasteboard = UIPasteboard.general
|
|
328
332
|
|
|
329
|
-
let
|
|
330
|
-
|
|
333
|
+
let staticImageTypes = [
|
|
334
|
+
"public.png",
|
|
335
|
+
"public.jpeg",
|
|
336
|
+
"public.tiff",
|
|
337
|
+
"public.heic",
|
|
338
|
+
"public.heif",
|
|
339
|
+
"public.image",
|
|
340
|
+
"org.webmproject.webp",
|
|
341
|
+
"public.webp",
|
|
342
|
+
"image/webp"
|
|
343
|
+
]
|
|
331
344
|
|
|
332
345
|
var gifDataItems: [Data] = []
|
|
333
346
|
var staticImages: [UIImage] = []
|
|
@@ -595,6 +608,15 @@ class ExpoPasteInputView: ExpoView {
|
|
|
595
608
|
deinit {
|
|
596
609
|
stopMonitoring()
|
|
597
610
|
}
|
|
611
|
+
|
|
612
|
+
private func hasPasteboardData(forAnyTypeIn types: Set<String>, pasteboard: UIPasteboard) -> Bool {
|
|
613
|
+
for type in types {
|
|
614
|
+
if let data = pasteboard.data(forPasteboardType: type), !data.isEmpty {
|
|
615
|
+
return true
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return false
|
|
619
|
+
}
|
|
598
620
|
}
|
|
599
621
|
|
|
600
622
|
extension UIImage {
|
package/package.json
CHANGED