diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 84364f2ef7ff..38855f1595a0 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -91,6 +91,16 @@
+
+
+
+
+
+
+
+
+
+
createNativeModules(
List modules = new ArrayList<>();
modules.add(new StartupTimer(reactContext));
+ modules.add(new ShareActionHandlerModule(reactContext));
return modules;
}
diff --git a/android/app/src/main/java/com/expensify/chat/MainActivity.kt b/android/app/src/main/java/com/expensify/chat/MainActivity.kt
index 935ba8c8825f..0969a2c9b4d3 100644
--- a/android/app/src/main/java/com/expensify/chat/MainActivity.kt
+++ b/android/app/src/main/java/com/expensify/chat/MainActivity.kt
@@ -1,18 +1,21 @@
package com.expensify.chat
-import expo.modules.ReactActivityDelegateWrapper
-
+import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
+import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.WindowInsets
import com.expensify.chat.bootsplash.BootSplash
+import com.expensify.chat.intentHandler.ImageIntentHandler
+import com.expensify.chat.intentHandler.IntentHandlerFactory
import com.expensify.reactnativekeycommand.KeyCommandModule
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
+import expo.modules.ReactActivityDelegateWrapper
class MainActivity : ReactActivity() {
/**
@@ -34,6 +37,9 @@ class MainActivity : ReactActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
BootSplash.init(this)
super.onCreate(null)
+ Log.i("ImageIntentHandler", "On create")
+
+
if (resources.getBoolean(R.bool.portrait_only)) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
@@ -50,6 +56,21 @@ class MainActivity : ReactActivity() {
defaultInsets.systemWindowInsetBottom
)
}
+
+ if (intent != null) {
+ handleIntent(intent)
+ }
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+ setIntent(intent) // Must store the new intent unless getIntent() will return the old one
+ handleIntent(intent)
+ }
+
+ private fun handleIntent(intent: Intent) {
+ val intentHandler = IntentHandlerFactory.getIntentHandler(this, intent.type)
+ intentHandler?.handle(intent)
}
/**
diff --git a/android/app/src/main/java/com/expensify/chat/MainApplication.kt b/android/app/src/main/java/com/expensify/chat/MainApplication.kt
index 2362af009979..a6e762c82e63 100644
--- a/android/app/src/main/java/com/expensify/chat/MainApplication.kt
+++ b/android/app/src/main/java/com/expensify/chat/MainApplication.kt
@@ -29,6 +29,7 @@ class MainApplication : MultiDexApplication(), ReactApplication {
add(BootSplashPackage())
add(ExpensifyAppPackage())
add(RNTextInputResetPackage())
+// add(ShareExtensionHandlerPackage())
}
override fun getJSMainModuleName() = ".expo/.virtual-metro-entry"
diff --git a/android/app/src/main/java/com/expensify/chat/ShareActionHandlerModule.kt b/android/app/src/main/java/com/expensify/chat/ShareActionHandlerModule.kt
new file mode 100644
index 000000000000..b6e6bf212362
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/ShareActionHandlerModule.kt
@@ -0,0 +1,34 @@
+package com.expensify.chat
+
+import android.content.Context
+import android.util.Log
+import com.expensify.chat.intentHandler.IntentHandlerConstants
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.bridge.Callback
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.bridge.ReactContextBaseJavaModule
+import com.facebook.react.bridge.ReactMethod
+
+class ShareActionHandlerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
+ override fun getName() = "ShareActionHandlerModule"
+
+ @ReactMethod
+ fun processFiles(callback: Callback) {
+ try {
+ val sharedPreferences = reactApplicationContext.getSharedPreferences(IntentHandlerConstants.preferencesFile, Context.MODE_PRIVATE)
+ val fileSet = sharedPreferences.getStringSet(IntentHandlerConstants.fileArrayProperty, setOf())
+ val fileArray: ArrayList = ArrayList(fileSet)
+
+ val resultArray = Arguments.createArray()
+ for (file in fileArray) {
+ resultArray.pushString(file)
+ }
+
+ callback.invoke(resultArray)
+ } catch (exception: Exception) {
+ Log.e("ImageIntentHandler", exception.toString())
+ callback.invoke(exception.toString(), null)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/expensify/chat/image/ImageUtils.kt b/android/app/src/main/java/com/expensify/chat/image/ImageUtils.kt
new file mode 100644
index 000000000000..1fa176f04dac
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/image/ImageUtils.kt
@@ -0,0 +1,114 @@
+package com.expensify.chat.image
+
+import android.content.Context
+import android.net.Uri
+import android.os.Environment
+import android.util.Log
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
+
+
+object ImageUtils {
+ private const val tag = "ImageUtils"
+ private const val maxPictureWidth = 2400
+ private const val optimalPictureSize = maxPictureWidth * maxPictureWidth
+ private const val defaultImageExtension = ".jpg"
+
+ private fun getUniqueImageFilePrefix(): String {
+ return System.currentTimeMillis().toString()
+ }
+
+ /**
+ * Checks if external storage is available.
+ *
+ * @return true if external storage is available, mounted and writable, false otherwise.
+ */
+ private fun isExternalStorageAvailable(): Boolean {
+ // Make sure the media storage is mounted (MEDIA_MOUNTED implies writable)
+ val state: String = Environment.getExternalStorageState()
+ if (state != Environment.MEDIA_MOUNTED) {
+ Log.w(tag, "External storage requested but not available" )
+ return false
+ }
+ return true
+ }
+
+ /**
+ * Synchronous method
+ *
+ * @param context
+ * @param imageUri
+ * @param destinationFile
+ * @throws IOException
+ */
+ @Throws(IOException::class)
+ fun saveImageFromMediaProviderUri(imageUri: Uri?, destinationFile: File?, context: Context) {
+ val inputStream: InputStream? = imageUri?.let { context.contentResolver.openInputStream(it) }
+ val outputStream: OutputStream = FileOutputStream(destinationFile)
+ inputStream?.use { input ->
+ outputStream.use { output ->
+ input.copyTo(output)
+ }
+ }
+ }
+
+ /**
+ * Creates an image file into the internal or external storage.
+ *
+ * @param context
+ * @return
+ * @throws IOException
+ */
+ @Throws(IOException::class)
+ fun createImageFile(context: Context): File {
+
+ // Create an image file name
+ val file: File = File.createTempFile(
+ getUniqueImageFilePrefix(),
+ defaultImageExtension,
+ getPhotoDirectory(context)
+ )
+ Log.i(tag, "Created a temporary file for the photo at" + file.absolutePath)
+ return file
+ }
+
+ /**
+ * Determines where the photo directory is based on if we can use external storage or not
+ *
+ * @param context
+ * @return File the directory
+ */
+ private fun getPhotoDirectory(context: Context): File? {
+ val photoDirectory: File = if (isExternalStorageAvailable()) File(
+ context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "Expensify"
+ ) else File(context.filesDir.absolutePath, "Expensify")
+ if (!photoDirectory.exists()) {
+ photoDirectory.mkdir()
+ }
+ return photoDirectory
+ }
+
+ /**
+ * Copy the given Uri to storage
+ *
+ * @param uri
+ * @param context
+ * @return The absolute path of the image
+ */
+ fun copyUriToStorage(uri: Uri?, context: Context): String? {
+ var resultingPath: String? = null
+ try {
+ val imageFile: File = createImageFile(context)
+ saveImageFromMediaProviderUri(uri, imageFile, context)
+ resultingPath = imageFile.absolutePath
+ Log.i("ImageIntentHandler", "save image$resultingPath")
+
+ } catch (ex: IOException) {
+ Log.e(tag, "Couldn't save image from intent", ex)
+ }
+ return resultingPath
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/expensify/chat/intentHandler/AbstractIntentHandler.kt b/android/app/src/main/java/com/expensify/chat/intentHandler/AbstractIntentHandler.kt
new file mode 100644
index 000000000000..a58c687bee56
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/intentHandler/AbstractIntentHandler.kt
@@ -0,0 +1,5 @@
+package com.expensify.chat.intentHandler
+
+abstract class AbstractIntentHandler: IntentHandler {
+ override fun onCompleted() {}
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/expensify/chat/intentHandler/ImageIntentHandler.kt b/android/app/src/main/java/com/expensify/chat/intentHandler/ImageIntentHandler.kt
new file mode 100644
index 000000000000..14d8a6f163c4
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/intentHandler/ImageIntentHandler.kt
@@ -0,0 +1,87 @@
+package com.expensify.chat.intentHandler
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.util.Log
+import com.expensify.chat.image.ImageUtils.copyUriToStorage
+
+
+object IntentHandlerConstants {
+ const val preferencesFile = "shareActionHandler"
+ const val fileArrayProperty = "filePaths"
+}
+
+
+class ImageIntentHandler(private val context: Context) : AbstractIntentHandler() {
+ override fun handle(intent: Intent?): Boolean {
+ Log.i("ImageIntentHandler", "Handle intent" + intent.toString())
+ if (intent == null) {
+ return false
+ }
+
+ val action: String? = intent.action
+ val type: String = intent.type ?: return false
+
+ if(!type.startsWith("image/")) return false
+
+ when(action) {
+ Intent.ACTION_SEND -> {
+ Log.i("ImageIntentHandler", "Handle receive single image")
+ handleSingleImageIntent(intent, context)
+ onCompleted()
+ return true
+ }
+ Intent.ACTION_SEND_MULTIPLE -> {
+ handleMultipleImagesIntent(intent, context)
+ onCompleted()
+ return true
+ }
+ }
+ return false
+ }
+
+ private fun handleSingleImageIntent(intent: Intent, context: Context) {
+ (intent.getParcelableExtra(Intent.EXTRA_STREAM))?.let { imageUri ->
+
+ Log.i("ImageIntentHandler", "handleSingleImageIntent$imageUri")
+ // Update UI to reflect image being shared
+ if (imageUri == null) {
+ return
+ }
+
+ val fileArrayList: ArrayList = ArrayList()
+ val resultingPath: String? = copyUriToStorage(imageUri, context)
+ if (resultingPath != null) {
+ fileArrayList.add(resultingPath)
+ val sharedPreferences = context.getSharedPreferences(IntentHandlerConstants.preferencesFile, Context.MODE_PRIVATE)
+ val editor = sharedPreferences.edit()
+ editor.putStringSet(IntentHandlerConstants.fileArrayProperty, fileArrayList.toSet())
+ editor.apply()
+ }
+ }
+ }
+
+ private fun handleMultipleImagesIntent(intent: Intent, context: Context) {
+
+ val resultingImagePaths = ArrayList()
+
+ (intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM))?.let { imageUris ->
+ for (imageUri in imageUris) {
+ val resultingPath: String? = copyUriToStorage(imageUri, context)
+ if (resultingPath != null) {
+ resultingImagePaths.add(resultingPath)
+ }
+ }
+ }
+// Yapl.getInstance().callIntentCallback(resultingImagePaths)
+ }
+
+ override fun onCompleted() {
+ val uri: Uri = Uri.parse("new-expensify://share/root")
+ val deepLinkIntent = Intent(Intent.ACTION_VIEW, uri)
+ deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ context.startActivity(deepLinkIntent)
+ }
+
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/expensify/chat/intentHandler/IntentHandler.kt b/android/app/src/main/java/com/expensify/chat/intentHandler/IntentHandler.kt
new file mode 100644
index 000000000000..6cd93dff276a
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/intentHandler/IntentHandler.kt
@@ -0,0 +1,8 @@
+package com.expensify.chat.intentHandler
+
+import android.content.Intent
+
+interface IntentHandler {
+ fun handle(intent: Intent?): Boolean
+ fun onCompleted()
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/expensify/chat/intentHandler/IntentHandlerFactory.kt b/android/app/src/main/java/com/expensify/chat/intentHandler/IntentHandlerFactory.kt
new file mode 100644
index 000000000000..c89af09e2b50
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/intentHandler/IntentHandlerFactory.kt
@@ -0,0 +1,14 @@
+package com.expensify.chat.intentHandler
+
+import android.content.Context
+
+object IntentHandlerFactory {
+ fun getIntentHandler(context: Context, mimeType: String?): IntentHandler? {
+ if (mimeType == null) return null
+ return when {
+ mimeType.startsWith("image/") -> ImageIntentHandler(context)
+ // Add other cases like video/*, application/pdf etc.
+ else -> null
+ }
+ }
+}
\ No newline at end of file
diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj
index 317b79c19c0d..8fc9e8ae99c4 100644
--- a/ios/NewExpensify.xcodeproj/project.pbxproj
+++ b/ios/NewExpensify.xcodeproj/project.pbxproj
@@ -39,11 +39,13 @@
BDB853621F354EBB84E619C2 /* ExpensifyNewKansas-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = D2AFB39EC1D44BF9B91D3227 /* ExpensifyNewKansas-MediumItalic.otf */; };
DD79042B2792E76D004484B4 /* RCTBootSplash.m in Sources */ = {isa = PBXBuildFile; fileRef = DD79042A2792E76D004484B4 /* RCTBootSplash.m */; };
DDCB2E57F334C143AC462B43 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D20D83B0E39BA6D21761E72 /* ExpoModulesProvider.swift */; };
- E51DC681C7DEE40AEBDDFBFE /* (null) in Frameworks */ = {isa = PBXBuildFile; };
+ E51DC681C7DEE40AEBDDFBFE /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
E5647A4A2B8E0CE40047156F /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5647A492B8E0CE40047156F /* ShareViewController.swift */; };
E5647A4D2B8E0CE40047156F /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E5647A4B2B8E0CE40047156F /* MainInterface.storyboard */; };
E5647A512B8E0CE40047156F /* ShareMenuExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = E5647A472B8E0CE20047156F /* ShareMenuExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
- E5CB2F182B7F834000B63003 /* (null) in Embed Foundation Extensions */ = {isa = PBXBuildFile; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ E5647A5B2B9203B20047156F /* RCTShareActionHandlerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = E5647A5A2B9203B10047156F /* RCTShareActionHandlerModule.m */; };
+ E5647A5C2B9203B20047156F /* RCTShareActionHandlerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = E5647A5A2B9203B10047156F /* RCTShareActionHandlerModule.m */; };
+ E5CB2F182B7F834000B63003 /* BuildFile in Embed Foundation Extensions */ = {isa = PBXBuildFile; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9DF872C2525201700607FDC /* AirshipConfig.plist */; };
ED222ED90E074A5481A854FA /* ExpensifyNeue-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8B28D84EF339436DBD42A203 /* ExpensifyNeue-BoldItalic.otf */; };
F0C450EA2705020500FD2970 /* colors.json in Resources */ = {isa = PBXBuildFile; fileRef = F0C450E92705020500FD2970 /* colors.json */; };
@@ -82,7 +84,7 @@
dstSubfolderSpec = 13;
files = (
7FD73CA22B23CE9500420AF3 /* NotificationServiceExtension.appex in Embed Foundation Extensions */,
- E5CB2F182B7F834000B63003 /* (null) in Embed Foundation Extensions */,
+ E5CB2F182B7F834000B63003 /* BuildFile in Embed Foundation Extensions */,
E5647A512B8E0CE40047156F /* ShareMenuExtension.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
@@ -150,6 +152,8 @@
E5647A492B8E0CE40047156F /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; };
E5647A4C2B8E0CE40047156F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; };
E5647A4E2B8E0CE40047156F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ E5647A592B9202B50047156F /* RCTShareActionHandlerModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTShareActionHandlerModule.h; sourceTree = ""; };
+ E5647A5A2B9203B10047156F /* RCTShareActionHandlerModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTShareActionHandlerModule.m; sourceTree = ""; };
E704648954784DDFBAADF568 /* ExpensifyMono-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyMono-Regular.otf"; path = "../assets/fonts/native/ExpensifyMono-Regular.otf"; sourceTree = ""; };
E750C93A45B47BDC5149C5AA /* Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig"; sourceTree = ""; };
E9DF872C2525201700607FDC /* AirshipConfig.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AirshipConfig.plist; sourceTree = ""; };
@@ -173,8 +177,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- E51DC681C7DEE40AEBDDFBFE /* (null) in Frameworks */,
- E51DC681C7DEE40AEBDDFBFE /* (null) in Frameworks */,
+ E51DC681C7DEE40AEBDDFBFE /* BuildFile in Frameworks */,
+ E51DC681C7DEE40AEBDDFBFE /* BuildFile in Frameworks */,
5B8996A7D8B007ECC41919E1 /* libPods-NewExpensify.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -280,6 +284,8 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
+ E5647A5A2B9203B10047156F /* RCTShareActionHandlerModule.m */,
+ E5647A592B9202B50047156F /* RCTShareActionHandlerModule.h */,
374FB8D528A133A7000D84EF /* OriginImageRequestHandler.h */,
374FB8D628A133FE000D84EF /* OriginImageRequestHandler.mm */,
F0C450E92705020500FD2970 /* colors.json */,
@@ -890,6 +896,7 @@
0CDA8E35287DD650004ECBEC /* AppDelegate.mm in Sources */,
7041848626A8E47D00E09F4D /* RCTStartupTimer.m in Sources */,
7F5E81F06BCCF61AD02CEA06 /* ExpoModulesProvider.swift in Sources */,
+ E5647A5C2B9203B20047156F /* RCTShareActionHandlerModule.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -897,6 +904,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ E5647A5B2B9203B20047156F /* RCTShareActionHandlerModule.m in Sources */,
18D050E0262400AF000D658B /* BridgingFile.swift in Sources */,
0F5E5350263B73FD004CA14F /* EnvironmentChecker.m in Sources */,
374FB8D728A133FE000D84EF /* OriginImageRequestHandler.mm in Sources */,
@@ -2351,6 +2359,7 @@
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
+ OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = com.expensify.chat.dev.ShareMenuExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2434,6 +2443,7 @@
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
+ OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = com.expensify.chat.dev.ShareMenuExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2517,6 +2527,7 @@
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
+ OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = com.expensify.chat.dev.ShareMenuExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2594,6 +2605,7 @@
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
+ OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.expensify.chat.dev.ShareMenuExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2670,6 +2682,7 @@
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
+ OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.expensify.chat.dev.ShareMenuExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2746,6 +2759,7 @@
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
+ OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.expensify.chat.dev.ShareMenuExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
diff --git a/ios/RCTShareActionHandlerModule.h b/ios/RCTShareActionHandlerModule.h
new file mode 100644
index 000000000000..ee8d186edb0d
--- /dev/null
+++ b/ios/RCTShareActionHandlerModule.h
@@ -0,0 +1,16 @@
+//
+// RCTShareActionHandlerModule.h
+// NewExpensify
+//
+// Created by Bartek Krasoń on 01/03/2024.
+//
+
+#ifndef RCTShareActionHandlerModule_h
+#define RCTShareActionHandlerModule_h
+
+#import
+
+@interface RCTShareActionHandlerModule : NSObject
+@end
+
+#endif /* RCTShareActionHandlerModule_h */
diff --git a/ios/RCTShareExtensionHandlerModule.m b/ios/RCTShareActionHandlerModule.m
similarity index 79%
rename from ios/RCTShareExtensionHandlerModule.m
rename to ios/RCTShareActionHandlerModule.m
index 569e0da8b71a..269faec4f0a4 100644
--- a/ios/RCTShareExtensionHandlerModule.m
+++ b/ios/RCTShareActionHandlerModule.m
@@ -1,22 +1,21 @@
//
-// RCTShareExtensionHandlerModule.m
+// RCTShareActionHandlerModule.m
// NewExpensify
//
-// Created by Bartek Krasoń on 23/02/2024.
+// Created by Bartek Krasoń on 01/03/2024.
//
#import
-#import "ios:NewExpensify:RCTShareExtensionHandlerModule.h"
+#import "RCTShareActionHandlerModule.h"
#import
NSString *const ShareExtensionGroupIdentifier = @"group.com.new-expensify";
NSString *const ShareExtensionFilesKey = @"ShareFiles";
NSString *const ShareImageFileExtension = @".png";
-@implementation RCTShareExtensionHandlerModule
+@implementation RCTShareActionHandlerModule
-// To export a module named RCTCalendarModule
-RCT_EXPORT_MODULE(RCTShareExtensionHandlerModule);
+RCT_EXPORT_MODULE(RCTShareActionHandlerModule);
RCT_EXPORT_METHOD(processFiles:(RCTResponseSenderBlock)callback)
{
@@ -38,10 +37,10 @@ @implementation RCTShareExtensionHandlerModule
NSArray *imageSrcPath = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:sharedImagesFolderPath error:&error];
if (imageSrcPath.count == 0) {
- NSLog(@"handleShareExtension Failed to find images in 'sharedImagesFolderPath'");
+ NSLog(@"handleShareAction Failed to find images in 'sharedImagesFolderPath'");
return;
}
- NSLog(@"handleShareExtension shared %lu images", imageSrcPath.count);
+ NSLog(@"handleShareAction shared %lu images", imageSrcPath.count);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
@@ -49,14 +48,14 @@ @implementation RCTShareExtensionHandlerModule
for (int i = 0; i < imageSrcPath.count; i++) {
if (imageSrcPath[i] == NULL) {
- NSLog(@"handleShareExtension Invalid image in position %d, imageSrcPath[i] is nil", i);
+ NSLog(@"handleShareAction Invalid image in position %d, imageSrcPath[i] is nil", i);
continue;
}
- NSLog(@"handleShareExtension Valid image in position %d", i);
+ NSLog(@"handleShareAction Valid image in position %d", i);
NSString *srcImageAbsolutePath = [sharedImagesFolderPath stringByAppendingPathComponent:imageSrcPath[i]];
UIImage *smartScanImage = [[UIImage alloc] initWithContentsOfFile:srcImageAbsolutePath];
if (smartScanImage == NULL) {
- NSLog(@"handleShareExtension Failed to load image %@", srcImageAbsolutePath);
+ NSLog(@"handleShareAction Failed to load image %@", srcImageAbsolutePath);
continue;
}
diff --git a/ios/ios:NewExpensify:RCTShareExtensionHandlerModule.h b/ios/ios:NewExpensify:RCTShareExtensionHandlerModule.h
deleted file mode 100644
index 161bb3496766..000000000000
--- a/ios/ios:NewExpensify:RCTShareExtensionHandlerModule.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// ios:NewExpensify:RCTShareExtensionHandlerModule.h
-// NewExpensify
-//
-// Created by Bartek Krasoń on 23/02/2024.
-//
-
-#ifndef ios_NewExpensify_RCTShareExtensionHandlerModule_h
-#define ios_NewExpensify_RCTShareExtensionHandlerModule_h
-
-#import
-@interface RCTShareExtensionHandlerModule : NSObject
-@end
-
-#endif /* ios_NewExpensify_RCTShareExtensionHandlerModule_h */
diff --git a/src/modules/ShareActionHandlerModule.ts b/src/modules/ShareActionHandlerModule.ts
new file mode 100644
index 000000000000..34add7ae6e6a
--- /dev/null
+++ b/src/modules/ShareActionHandlerModule.ts
@@ -0,0 +1,9 @@
+import {NativeModules} from 'react-native';
+
+const {ShareActionHandlerModule} = NativeModules;
+
+type ShareActionHandlerType = {
+ processFiles(callback: (array: string[]) => void): void;
+};
+
+export default ShareActionHandlerModule as ShareActionHandlerType;
diff --git a/src/modules/ShareExtensionHandlerModule.ts b/src/modules/ShareExtensionHandlerModule.ts
deleted file mode 100644
index a283189ca9c6..000000000000
--- a/src/modules/ShareExtensionHandlerModule.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import {NativeModules} from 'react-native';
-
-const {ShareExtensionHandlerModule} = NativeModules;
-
-type ShareExtensionHandlerType = {
- processFiles(callback: (array: string[]) => void): void;
-};
-
-export default ShareExtensionHandlerModule as ShareExtensionHandlerType;
diff --git a/src/pages/share/ShareRootPage.tsx b/src/pages/share/ShareRootPage.tsx
index b482d15a1030..028e7439a0df 100644
--- a/src/pages/share/ShareRootPage.tsx
+++ b/src/pages/share/ShareRootPage.tsx
@@ -1,6 +1,6 @@
import React, {useCallback, useEffect, useRef} from 'react';
import type {AppStateStatus} from 'react-native';
-import {AppState, View} from 'react-native';
+import {AppState, Platform, View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -15,7 +15,7 @@ import Navigation from '@navigation/Navigation';
import OnyxTabNavigator, {TopTab} from '@navigation/OnyxTabNavigator';
import MoneyRequestParticipantsSelector from '@pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector';
import CONST from '@src/CONST';
-import ShareExtensionHandlerModule from '@src/modules/ShareExtensionHandlerModule';
+import ShareActionHandlerModule from '@src/modules/ShareActionHandlerModule';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Report} from '@src/types/onyx';
@@ -39,11 +39,14 @@ function ShareRootPage({selectedTab, iou}: ShareRootPageProps) {
const handleAppStateChange = (nextAppState: AppStateStatus) => {
if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
- ShareExtensionHandlerModule?.processFiles((processedFiles) => {
+ console.log('PROCESSED FILES ATTEMPT');
+
+ ShareActionHandlerModule.processFiles((processedFiles) => {
// eslint-disable-next-line no-console
console.log('PROCESSED FILES ', processedFiles);
});
}
+ console.log('AppState', nextAppState);
appState.current = nextAppState;
// eslint-disable-next-line no-console
@@ -51,10 +54,10 @@ function ShareRootPage({selectedTab, iou}: ShareRootPageProps) {
};
useEffect(() => {
- const appStateSubscription = AppState.addEventListener('change', handleAppStateChange);
+ const changeSubscription = AppState.addEventListener('change', handleAppStateChange);
return () => {
- appStateSubscription.remove();
+ changeSubscription.remove();
};
}, []);
@@ -65,12 +68,13 @@ function ShareRootPage({selectedTab, iou}: ShareRootPageProps) {
const goToNextStep = useCallback(() => {
// const nextStepIOUType = numberOfParticipants.current === 1 ? CONST.IOU.TYPE.REQUEST : CONST.IOU.TYPE.SPLIT;
const nextStepIOUType = CONST.IOU.TYPE.REQUEST;
- IOU.startMoneyRequest_temporaryForRefactor(optimisticReportID, false, CONST.IOU.REQUEST_TYPE.SCAN);
+ // IOU.startMoneyRequest_temporaryForRefactor(optimisticReportID, false, CONST.IOU.REQUEST_TYPE.SCAN);
IOU.setMoneyRequestTag(transactionID, '');
- IOU.resetMoneyRequestCategory_temporaryForRefactor(transactionID);
+ // IOU.resetMoneyRequestCategory_temporaryForRefactor(transactionID);
Navigation.navigate(ROUTES.SHARE_SCAN_CONFIRM.getRoute(nextStepIOUType, transactionID, selectedReportID.current || optimisticReportID));
}, [transactionID, optimisticReportID]);
+ console.log('share root page');
return (
({
- selectedTab: {
- key: `${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.RECEIPT_TAB_ID}`,
- },
- // @ts-expect-error To fix
- iou: {
- key: ONYXKEYS.IOU,
- },
-})(ShareRootPage);
+export default ShareRootPage;