expo-paste-input 0.1.8 → 0.1.9
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$enhanceOnTextContextMenuItem$callback$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$enhanceOnTextContextMenuItem$callback$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$enhanceOnTextContextMenuItem$callback$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 +181 -128
- package/ios/ExpoPasteInputView.swift +65 -10
- 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,109 +178,182 @@ 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
187
|
// Set up a custom ActionMode.Callback to intercept paste from context menu
|
|
205
188
|
// This is the most reliable way to intercept paste before the toast appears
|
|
206
|
-
|
|
189
|
+
val callback = object : ActionMode.Callback {
|
|
207
190
|
override fun onCreateActionMode(mode: ActionMode?, menu: android.view.Menu?): Boolean {
|
|
208
191
|
// Delegate to original callback if it exists
|
|
209
|
-
return
|
|
192
|
+
return getOriginalActionModeCallback()?.onCreateActionMode(mode, menu) ?: true
|
|
210
193
|
}
|
|
211
194
|
|
|
212
195
|
override fun onPrepareActionMode(mode: ActionMode?, menu: android.view.Menu?): Boolean {
|
|
213
196
|
// Delegate to original callback if it exists
|
|
214
|
-
return
|
|
197
|
+
return getOriginalActionModeCallback()?.onPrepareActionMode(mode, menu) ?: false
|
|
215
198
|
}
|
|
216
199
|
|
|
217
200
|
override fun onActionItemClicked(mode: ActionMode?, item: android.view.MenuItem?): Boolean {
|
|
218
201
|
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
|
-
}
|
|
202
|
+
return handlePasteFromActionMode(editText, mode, item, getOriginalActionModeCallback())
|
|
285
203
|
}
|
|
286
204
|
|
|
287
205
|
// For other actions, delegate to original callback or return false
|
|
288
|
-
return
|
|
206
|
+
return getOriginalActionModeCallback()?.onActionItemClicked(mode, item) ?: false
|
|
289
207
|
}
|
|
290
208
|
|
|
291
209
|
override fun onDestroyActionMode(mode: ActionMode?) {
|
|
292
210
|
// Delegate to original callback if it exists
|
|
293
|
-
|
|
211
|
+
getOriginalActionModeCallback()?.onDestroyActionMode(mode)
|
|
294
212
|
}
|
|
295
213
|
}
|
|
296
214
|
|
|
297
|
-
|
|
215
|
+
customSelectionActionModeCallback = callback
|
|
216
|
+
editText.customSelectionActionModeCallback = customSelectionActionModeCallback
|
|
217
|
+
|
|
218
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
219
|
+
customInsertionActionModeCallback = callback
|
|
220
|
+
editText.customInsertionActionModeCallback = customInsertionActionModeCallback
|
|
221
|
+
}
|
|
298
222
|
|
|
299
223
|
} catch (e: Exception) {
|
|
300
224
|
// If ActionMode.Callback approach fails, we'll rely on OnReceiveContentListener
|
|
301
225
|
// which should still work but may show the toast briefly
|
|
302
226
|
}
|
|
303
227
|
}
|
|
228
|
+
|
|
229
|
+
private fun getOriginalActionModeCallback(): ActionMode.Callback? {
|
|
230
|
+
// Cursor/insertion menu and selection menu can use different callbacks.
|
|
231
|
+
// Prefer insertion callback first for insertion-mode paste.
|
|
232
|
+
return originalInsertionActionModeCallback ?: originalSelectionActionModeCallback
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private fun handlePasteFromActionMode(
|
|
236
|
+
editText: EditText,
|
|
237
|
+
mode: ActionMode?,
|
|
238
|
+
item: android.view.MenuItem,
|
|
239
|
+
originalCallback: ActionMode.Callback?
|
|
240
|
+
): Boolean {
|
|
241
|
+
val clipboard = editText.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
242
|
+
val parsed = parseClipboardPayload(clipboard.primaryClip, editText.context)
|
|
243
|
+
|
|
244
|
+
if (parsed.hasImages) {
|
|
245
|
+
markSuppressOnReceiveContent()
|
|
246
|
+
processMultipleImagePaste(parsed.imageUris, parsed.gifUris)
|
|
247
|
+
mode?.finish()
|
|
248
|
+
return true
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
val text = parsed.textContent
|
|
252
|
+
if (!text.isNullOrEmpty()) {
|
|
253
|
+
var handled = originalCallback?.onActionItemClicked(mode, item) ?: false
|
|
254
|
+
if (!handled) {
|
|
255
|
+
handled = editText.onTextContextMenuItem(item.itemId)
|
|
256
|
+
}
|
|
257
|
+
if (!handled) {
|
|
258
|
+
insertTextAtCursor(editText, text)
|
|
259
|
+
handled = true
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (handled) {
|
|
263
|
+
// On Android < 12, ActionMode path is the only reliable callback for text.
|
|
264
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
|
265
|
+
handleTextPaste(text)
|
|
266
|
+
}
|
|
267
|
+
markSuppressOnReceiveContent()
|
|
268
|
+
mode?.finish()
|
|
269
|
+
return true
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
handleUnsupportedPaste()
|
|
274
|
+
mode?.finish()
|
|
275
|
+
return true
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private fun parseClipboardPayload(
|
|
279
|
+
clipData: android.content.ClipData?,
|
|
280
|
+
sourceContext: Context
|
|
281
|
+
): ClipboardPayload {
|
|
282
|
+
if (clipData == null || clipData.itemCount <= 0) {
|
|
283
|
+
return ClipboardPayload(emptyList(), emptyList(), null)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
val imageUris = mutableListOf<Uri>()
|
|
287
|
+
val gifUris = mutableListOf<Uri>()
|
|
288
|
+
var textContent: String? = null
|
|
289
|
+
|
|
290
|
+
for (i in 0 until clipData.itemCount) {
|
|
291
|
+
val clipItem = clipData.getItemAt(i)
|
|
292
|
+
val uri = clipItem.uri
|
|
293
|
+
if (uri != null) {
|
|
294
|
+
val mimeType = sourceContext.contentResolver.getType(uri)?.lowercase()
|
|
295
|
+
if (mimeType != null && mimeType.startsWith("image/")) {
|
|
296
|
+
if (mimeType == "image/gif") {
|
|
297
|
+
gifUris.add(uri)
|
|
298
|
+
} else {
|
|
299
|
+
imageUris.add(uri)
|
|
300
|
+
}
|
|
301
|
+
} else if (isLikelyImageUri(uri)) {
|
|
302
|
+
imageUris.add(uri)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (textContent == null) {
|
|
307
|
+
val text = clipItem.coerceToText(sourceContext)
|
|
308
|
+
if (!text.isNullOrEmpty()) {
|
|
309
|
+
textContent = text.toString()
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return ClipboardPayload(
|
|
315
|
+
imageUris = imageUris,
|
|
316
|
+
gifUris = gifUris,
|
|
317
|
+
textContent = textContent
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private fun isLikelyImageUri(uri: Uri): Boolean {
|
|
322
|
+
val fileName = uri.lastPathSegment?.lowercase() ?: return false
|
|
323
|
+
return fileName.endsWith(".png") ||
|
|
324
|
+
fileName.endsWith(".jpg") ||
|
|
325
|
+
fileName.endsWith(".jpeg") ||
|
|
326
|
+
fileName.endsWith(".gif") ||
|
|
327
|
+
fileName.endsWith(".webp") ||
|
|
328
|
+
fileName.endsWith(".heic") ||
|
|
329
|
+
fileName.endsWith(".heif")
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
private fun markSuppressOnReceiveContent() {
|
|
333
|
+
suppressOnReceiveContentUntilMs = SystemClock.elapsedRealtime() + 500L
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
private fun shouldSuppressOnReceiveContent(): Boolean {
|
|
337
|
+
return SystemClock.elapsedRealtime() <= suppressOnReceiveContentUntilMs
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private fun insertTextAtCursor(editText: EditText, text: String) {
|
|
341
|
+
val editable = editText.editableText ?: return
|
|
342
|
+
val start = editText.selectionStart
|
|
343
|
+
val end = editText.selectionEnd
|
|
344
|
+
|
|
345
|
+
val replaceStart = minOf(start, end).coerceAtLeast(0)
|
|
346
|
+
val replaceEnd = maxOf(start, end).coerceAtLeast(0)
|
|
347
|
+
|
|
348
|
+
if (replaceStart <= replaceEnd && replaceEnd <= editable.length) {
|
|
349
|
+
editable.replace(replaceStart, replaceEnd, text)
|
|
350
|
+
val newCursor = (replaceStart + text.length).coerceAtMost(editable.length)
|
|
351
|
+
editText.setSelection(newCursor)
|
|
352
|
+
} else {
|
|
353
|
+
editable.append(text)
|
|
354
|
+
editText.setSelection(editable.length)
|
|
355
|
+
}
|
|
356
|
+
}
|
|
304
357
|
|
|
305
358
|
private fun findTextInputInView(view: View?): View? {
|
|
306
359
|
if (view == null) return null
|
|
@@ -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,11 +148,11 @@ 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
154
|
let pasteboard = UIPasteboard.general
|
|
153
|
-
if pasteboard.
|
|
155
|
+
if pasteboard.hasStrings || wrapper.hasSupportedImageContent(in: pasteboard) {
|
|
154
156
|
return true
|
|
155
157
|
}
|
|
156
158
|
}
|
|
@@ -203,9 +205,8 @@ class ExpoPasteInputView: ExpoView {
|
|
|
203
205
|
|
|
204
206
|
// CRITICAL: Check for GIFs FIRST using explicit type queries
|
|
205
207
|
// This gets raw data without triggering UIImage conversion
|
|
206
|
-
let gifTypes = ["com.compuserve.gif", "public.gif", "image/gif"]
|
|
207
208
|
var hasGIF = false
|
|
208
|
-
for gifType in gifTypes {
|
|
209
|
+
for gifType in wrapper.gifTypes {
|
|
209
210
|
if let gifData = pasteboard.data(forPasteboardType: gifType), !gifData.isEmpty {
|
|
210
211
|
hasGIF = true
|
|
211
212
|
break
|
|
@@ -216,7 +217,7 @@ class ExpoPasteInputView: ExpoView {
|
|
|
216
217
|
if !hasGIF {
|
|
217
218
|
for item in pasteboard.items {
|
|
218
219
|
for (key, _) in item {
|
|
219
|
-
if gifTypes.contains(key) || key.lowercased().contains("gif") {
|
|
220
|
+
if wrapper.gifTypes.contains(key) || key.lowercased().contains("gif") {
|
|
220
221
|
hasGIF = true
|
|
221
222
|
break
|
|
222
223
|
}
|
|
@@ -243,8 +244,9 @@ class ExpoPasteInputView: ExpoView {
|
|
|
243
244
|
}
|
|
244
245
|
|
|
245
246
|
// Check if this looks like image data
|
|
246
|
-
let isImageKey = key.contains("image") || key.contains("png") || key.contains("jpeg") ||
|
|
247
|
-
|
|
247
|
+
let isImageKey = key.contains("image") || key.contains("png") || key.contains("jpeg") ||
|
|
248
|
+
key.contains("jpg") || key.contains("tiff") || key.contains("heic") ||
|
|
249
|
+
key.contains("heif") || key.contains("webp")
|
|
248
250
|
|
|
249
251
|
if isImageKey && (value is Data || value is UIImage) {
|
|
250
252
|
hasImageData = true
|
|
@@ -267,7 +269,7 @@ class ExpoPasteInputView: ExpoView {
|
|
|
267
269
|
|
|
268
270
|
// Fallback: check hasImages only if no image data found in items
|
|
269
271
|
// This is safer as we've already checked for GIFs above
|
|
270
|
-
if pasteboard.hasImages {
|
|
272
|
+
if pasteboard.hasImages || wrapper.hasPasteboardData(forAnyTypeIn: wrapper.webpTypes, pasteboard: pasteboard) {
|
|
271
273
|
DispatchQueue.main.async {
|
|
272
274
|
wrapper.processPasteboardContent()
|
|
273
275
|
}
|
|
@@ -326,8 +328,17 @@ class ExpoPasteInputView: ExpoView {
|
|
|
326
328
|
// This method is only called for image pastes
|
|
327
329
|
let pasteboard = UIPasteboard.general
|
|
328
330
|
|
|
329
|
-
let
|
|
330
|
-
|
|
331
|
+
let staticImageTypes = [
|
|
332
|
+
"public.png",
|
|
333
|
+
"public.jpeg",
|
|
334
|
+
"public.tiff",
|
|
335
|
+
"public.heic",
|
|
336
|
+
"public.heif",
|
|
337
|
+
"public.image",
|
|
338
|
+
"org.webmproject.webp",
|
|
339
|
+
"public.webp",
|
|
340
|
+
"image/webp"
|
|
341
|
+
]
|
|
331
342
|
|
|
332
343
|
var gifDataItems: [Data] = []
|
|
333
344
|
var staticImages: [UIImage] = []
|
|
@@ -595,6 +606,50 @@ class ExpoPasteInputView: ExpoView {
|
|
|
595
606
|
deinit {
|
|
596
607
|
stopMonitoring()
|
|
597
608
|
}
|
|
609
|
+
|
|
610
|
+
private func hasSupportedImageContent(in pasteboard: UIPasteboard) -> Bool {
|
|
611
|
+
if pasteboard.hasImages {
|
|
612
|
+
return true
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if hasPasteboardData(forAnyTypeIn: gifTypes.union(webpTypes), pasteboard: pasteboard) {
|
|
616
|
+
return true
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
for item in pasteboard.items {
|
|
620
|
+
for (key, value) in item {
|
|
621
|
+
let lowercasedKey = key.lowercased()
|
|
622
|
+
let isImageLikeType = lowercasedKey.contains("image") ||
|
|
623
|
+
lowercasedKey.contains("png") ||
|
|
624
|
+
lowercasedKey.contains("jpeg") ||
|
|
625
|
+
lowercasedKey.contains("jpg") ||
|
|
626
|
+
lowercasedKey.contains("tiff") ||
|
|
627
|
+
lowercasedKey.contains("heic") ||
|
|
628
|
+
lowercasedKey.contains("heif") ||
|
|
629
|
+
lowercasedKey.contains("gif") ||
|
|
630
|
+
lowercasedKey.contains("webp")
|
|
631
|
+
|
|
632
|
+
if isImageLikeType && (value is Data || value is UIImage) {
|
|
633
|
+
return true
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if value is UIImage {
|
|
637
|
+
return true
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return false
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
private func hasPasteboardData(forAnyTypeIn types: Set<String>, pasteboard: UIPasteboard) -> Bool {
|
|
646
|
+
for type in types {
|
|
647
|
+
if let data = pasteboard.data(forPasteboardType: type), !data.isEmpty {
|
|
648
|
+
return true
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return false
|
|
652
|
+
}
|
|
598
653
|
}
|
|
599
654
|
|
|
600
655
|
extension UIImage {
|
package/package.json
CHANGED