Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share extension Android and iOS implementation #54354

Draft
wants to merge 120 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 116 commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
410748b
setup share
BrtqKr Aug 28, 2024
3cbb982
wire up groups, update group id
BrtqKr Aug 28, 2024
38ec094
update app group id
BrtqKr Aug 28, 2024
b5e1641
fix single image share
BrtqKr Oct 1, 2024
7f82783
Merge remote-tracking branch 'origin/main' into brtqkr/wire-up-share-…
BrtqKr Oct 2, 2024
357b878
add tabs layout, wire up transaction setup
BrtqKr Oct 3, 2024
5871fa0
initial onyx setup
BrtqKr Oct 4, 2024
4562d4e
add mime type handling in the ios native module return object
BrtqKr Oct 4, 2024
06ac232
attachment wip
BrtqKr Oct 7, 2024
3c6946c
wire up share attachment, wire up message wip
BrtqKr Oct 7, 2024
f7d16af
add text
BrtqKr Oct 8, 2024
7b13b38
Submit Details Page in progress
filip-solecki Oct 14, 2024
b447164
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Oct 14, 2024
47e83df
Fix navigation
filip-solecki Oct 14, 2024
ee33b1e
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Oct 24, 2024
3dd5657
Clear code
filip-solecki Oct 24, 2024
f1b5f27
Support Android images sharing and preparation for other types
filip-solecki Oct 24, 2024
7dd0798
Handle text and other file types sharing on iOS
filip-solecki Oct 30, 2024
333b5a1
Handle text sharing for Android devices
filip-solecki Oct 30, 2024
82579c1
shareDetailsPage wip
Guccio163 Nov 1, 2024
ea0b0b8
Message visible
Guccio163 Nov 1, 2024
7c3ee53
textInput research
Guccio163 Nov 1, 2024
9cc6950
Merge branch 'main' of github.com:software-mansion-labs/expensify-app…
Guccio163 Nov 5, 2024
c73447f
Fix text files sharing on Android
filip-solecki Nov 6, 2024
a3022b9
clicking on users works without properly getting text and alternateText
Guccio163 Nov 8, 2024
ccb7120
working redirect, not working creating mult-people chats
Guccio163 Nov 14, 2024
caaac2e
Merge branch 'main' of github.com:software-mansion-labs/expensify-app…
Guccio163 Nov 14, 2024
83a92cc
adding users and creating chats fixed from main
Guccio163 Nov 14, 2024
b14584d
data extraction cleanup
Guccio163 Nov 15, 2024
1b07248
Merge branch 'brtqkr/wire-up-share-extension-ios' into Guccio163/shar…
Guccio163 Nov 15, 2024
a021fab
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Nov 18, 2024
9cdeebb
attachment visualising
Guccio163 Nov 19, 2024
de34abf
Merge branch 'brtqkr/wire-up-share-extension-ios' of github.com:softw…
Guccio163 Nov 19, 2024
c639945
share working, styling attachment to do
Guccio163 Nov 21, 2024
5f21f49
target details in submit added
Guccio163 Nov 21, 2024
68db412
Finish Submit flow, Fix description issue, close Modal after finishin…
filip-solecki Nov 21, 2024
35325d6
Merge branch 'brtqkr/wire-up-share-extension-ios' of github.com:softw…
Guccio163 Nov 22, 2024
286189a
Merge branch 'brtqkr/wire-up-share-extension-ios' into Guccio163/shar…
Guccio163 Nov 22, 2024
4fd6101
merge message
Guccio163 Nov 22, 2024
b457bab
Fix file uriPath on iOS and block sending file while sharing plain text
filip-solecki Nov 25, 2024
1930925
Handle URL sharing on iOS
filip-solecki Nov 27, 2024
43d8f08
Attachment Modal working for video and image, waiting for ldf
Guccio163 Nov 29, 2024
08c85e9
Fix PDF sharing for iOS
filip-solecki Nov 29, 2024
89bfbc4
Fix files handling on iOS
filip-solecki Dec 2, 2024
7dd929f
display pdf, image and video thumbnails, lacks aspectRatio
Guccio163 Dec 2, 2024
b960843
files and text working on ios, android failing with pdf
Guccio163 Dec 2, 2024
c4b3d65
return aspectRatio for videos on iOS
filip-solecki Dec 3, 2024
c354af4
return aspectRatio for videos on Android
filip-solecki Dec 3, 2024
1bbe686
PDF without thumbnail, opening Modal
Guccio163 Dec 3, 2024
ecca4b4
remove PDF opening Modal, left-aligned thumbnails
Guccio163 Dec 4, 2024
20cc5c1
wrapping in SafeAreaView
Guccio163 Dec 5, 2024
ff3127e
Cleanup and Submit fix
filip-solecki Dec 5, 2024
5f6b097
cleanup
Guccio163 Dec 5, 2024
a42a984
small restructure
Guccio163 Dec 6, 2024
b4c7481
unknown user mail display
Guccio163 Dec 9, 2024
f04e90f
Merge branch 'main' of github.com:software-mansion-labs/expensify-app…
Guccio163 Dec 9, 2024
f5c754c
requestMoney params fixing
Guccio163 Dec 10, 2024
f4a9288
dismissModal after submit working
Guccio163 Dec 11, 2024
021a098
Merge branch 'main' of github.com:software-mansion-labs/expensify-app…
Guccio163 Dec 11, 2024
fd90d8a
Merge branch 'main' of github.com:software-mansion-labs/expensify-app…
Guccio163 Dec 16, 2024
71e3475
unfinished alert when incorrect file format and redirect to home
Guccio163 Dec 16, 2024
eb0590a
unsupported file format alert and redirect working
Guccio163 Dec 16, 2024
c67b558
Merge branch 'main' of github.com:software-mansion-labs/expensify-app…
Guccio163 Dec 16, 2024
2276bb6
JS cleanup without SubmitDetailsPage
Guccio163 Dec 16, 2024
f8a33c2
SubmitDetailsPage with onSuccess comments, yet to change
Guccio163 Dec 16, 2024
d68cf92
Merge branch 'main' of github.com:software-mansion-labs/expensify-app…
Guccio163 Dec 16, 2024
08c7040
Clear Android files
filip-solecki Dec 17, 2024
11a8a52
Fix shared file's name
filip-solecki Dec 17, 2024
05e21ae
Remove redundant Log
filip-solecki Dec 17, 2024
9d1bf2d
Submit flow working
Guccio163 Dec 19, 2024
8e60c27
Merge branch 'brtqkr/wire-up-share-extension-ios' of github.com:softw…
Guccio163 Dec 19, 2024
bfe2682
Fix flicering Tabs
filip-solecki Dec 19, 2024
769908d
Fix submit request description
filip-solecki Dec 19, 2024
8f309af
Accept txt mimeType
filip-solecki Dec 19, 2024
e23dc6e
Fix file handling for iOS
filip-solecki Dec 19, 2024
f9ec294
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Dec 19, 2024
10bacbf
Fix TS error in Routes
filip-solecki Dec 20, 2024
4132cab
Fix TS in Report file
filip-solecki Dec 20, 2024
3770da6
Fix TS in ReportDetailsPage
filip-solecki Dec 20, 2024
6a61f98
Fix changed files ESLint check
filip-solecki Dec 20, 2024
5a048eb
Fix ESLint in dismissModalWithReport
filip-solecki Dec 20, 2024
ab547b5
Clean native files
filip-solecki Dec 20, 2024
b697ec8
Do not pass anonymous function causing rerenders
filip-solecki Dec 23, 2024
9d50aad
Add empty line in android files
filip-solecki Dec 23, 2024
813f5ac
rename intenthandler
filip-solecki Dec 23, 2024
869dc76
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Dec 23, 2024
f74f3da
create function for saving to shared
filip-solecki Dec 23, 2024
6ed8ad1
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Dec 31, 2024
e4c96ec
Remove redundant if statement
filip-solecki Jan 2, 2025
776446e
Remove redundant type and memoization
filip-solecki Jan 2, 2025
b8ddb52
Remove redundant object creation
filip-solecki Jan 2, 2025
63bfe9e
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Jan 2, 2025
55ef8fd
Check if files folder is not empty while deleting files
filip-solecki Jan 2, 2025
3bb13ca
Reuse getInternalStorageDirectory function
filip-solecki Jan 2, 2025
b92ada3
Remove lateinit usage
filip-solecki Jan 2, 2025
5301ebd
Replace set to NULL with remove
filip-solecki Jan 2, 2025
bd4d916
Create reusable function for saving files
filip-solecki Jan 2, 2025
3fa8535
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Jan 3, 2025
a8af760
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Jan 3, 2025
443f25e
Make RCTSahreActionHandlerModule more readable
filip-solecki Jan 3, 2025
693cc99
shareTab and submitTab changes before merging both tabs
Guccio163 Jan 6, 2025
a77dbaa
shareTabs duplicate code extracting and onFinish defaulting
Guccio163 Jan 6, 2025
e6f5ef1
Update comment to Onyx key
filip-solecki Jan 7, 2025
4460ebf
Fix snyk by using newest gson
filip-solecki Jan 7, 2025
f561b7e
Fix Onyx naming
filip-solecki Jan 7, 2025
1e5c644
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Jan 7, 2025
72c4acc
Fix TS
filip-solecki Jan 7, 2025
8146a84
Correct 'source' comment
filip-solecki Jan 7, 2025
aab0c4d
Fix typing in translations files
filip-solecki Jan 7, 2025
a4f49f5
Correct getOptimisticChatReport description
filip-solecki Jan 7, 2025
48fba1c
Fix ID typing
filip-solecki Jan 7, 2025
951a392
comments and ShareTab conditions
Guccio163 Jan 7, 2025
2594819
Merge branch 'brtqkr/wire-up-share-extension-ios' of github.com:softw…
Guccio163 Jan 7, 2025
bc618ff
get rid of onFinish from participants selector
Guccio163 Jan 7, 2025
d649547
Merge branch 'main' into brtqkr/wire-up-share-extension-ios
filip-solecki Jan 8, 2025
92a46e8
get rid of useMemo and rename variable
filip-solecki Jan 8, 2025
18defbf
Remove assertion from ShareActionHandlerModule
blazejkustra Jan 8, 2025
a012e2b
Rename ShareActionModule elements
filip-solecki Jan 8, 2025
12d4d7b
Fix changed files eslint
filip-solecki Jan 8, 2025
721e615
Fix default value for inexistent reportID
filip-solecki Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ dependencies {
implementation "com.squareup.okhttp3:okhttp-urlconnection:4.+"

implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0")

implementation("com.google.code.gson:gson:2.8.9")
}

apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin
Expand Down
46 changes: 46 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,52 @@
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/track-expense"/>
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/submit-expense"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />

<!-- Images -->
<data android:mimeType="image/jpg" />
<data android:mimeType="image/jpeg" />
<data android:mimeType="image/gif" />
<data android:mimeType="image/png" />
<data android:mimeType="image/tif" />
<data android:mimeType="image/tiff" />

<!-- Documents -->
<data android:mimeType="application/pdf" />
<data android:mimeType="application/msword" />
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
<data android:mimeType="application/rtf" />
<data android:mimeType="application/zip" />
<data android:mimeType="message/rfc822" />

<!-- Text / HTML -->
<data android:mimeType="text/plain" />
<data android:mimeType="text/html" />
<data android:mimeType="text/xml" />

<!-- Audio / Video -->
<data android:mimeType="audio/mpeg" />
<data android:mimeType="audio/aac" />
<data android:mimeType="audio/flac" />
<data android:mimeType="audio/wav" />
<data android:mimeType="audio/x-wav" />
<data android:mimeType="audio/mp3" />
<data android:mimeType="audio/vorbis" />
<data android:mimeType="audio/x-vorbis" />
<data android:mimeType="audio/opus" />

<data android:mimeType="video/mp4" />
<data android:mimeType="video/mp2t" />
<data android:mimeType="video/webm" />
<data android:mimeType="video/avc" />
<data android:mimeType="video/hevc" />
<data android:mimeType="video/x-vnd.on2.vp8" />
<data android:mimeType="video/x-vnd.on2.vp9" />
<data android:mimeType="video/av01" />

</intent-filter>
</activity>

<meta-data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public List<NativeModule> createNativeModules(
List<NativeModule> modules = new ArrayList<>();

modules.add(new StartupTimer(reactContext));
modules.add(new ShareActionHandlerModule(reactContext));

return modules;
}
Expand Down
25 changes: 23 additions & 2 deletions android/app/src/main/java/com/expensify/chat/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
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.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

import com.oblador.performance.RNPerformance

Expand Down Expand Up @@ -52,6 +54,25 @@ 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) {
try {
val intenthandler = IntentHandlerFactory.getIntentHandler(this, intent.type, intent.toString())
intenthandler?.handle(intent)
} catch (exception: Exception) {
Log.e("handleIntentException", exception.toString())
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.expensify.chat

import android.content.Context
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever
import com.expensify.chat.intenthandler.IntentHandlerConstants
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import android.util.Log
import com.facebook.react.bridge.ReactMethod
import org.json.JSONObject
import java.io.File

class ShareActionHandlerModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {

override fun getName(): String {
return "ShareActionHandlerModule"
}

@ReactMethod
fun processFiles(callback: Callback) {
try {
val sharedPreferences = reactApplicationContext.getSharedPreferences(
IntentHandlerConstants.preferencesFile,
Context.MODE_PRIVATE
)

val shareObjectString = sharedPreferences.getString(IntentHandlerConstants.shareObjectProperty, null)
if (shareObjectString == null) {
callback.invoke("No data found", null)
return
}

val shareObject = JSONObject(shareObjectString)
val content = shareObject.optString("content")
val mimeType = shareObject.optString("mimeType")
val fileUriPath = "file://$content"
val timestamp = System.currentTimeMillis()

val file = File(content)
if (!file.exists()) {
val textObject = JSONObject().apply {
put("id", "text")
put("content", content)
put("mimeType", "txt")
put("processedAt", timestamp)
}
callback.invoke(textObject.toString())
return
}

val identifier = file.name
var aspectRatio = 0.0f

if (mimeType.startsWith("image/")) {
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
BitmapFactory.decodeFile(content, options)
aspectRatio = if (options.outHeight != 0) options.outWidth.toFloat() / options.outHeight else 1.0f
} else if (mimeType.startsWith("video/")) {
val retriever = MediaMetadataRetriever()
try {
retriever.setDataSource(content)
val videoWidth = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toFloatOrNull() ?: 1f
val videoHeight = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toFloatOrNull() ?: 1f
if (videoHeight != 0f) aspectRatio = videoWidth / videoHeight
} catch (e: Exception) {
Log.e("ShareActionHandlerModule", "Error retrieving video metadata: ${e.message}")
} finally {
retriever.release()
}
}

val fileData = JSONObject().apply {
put("id", identifier)
put("content", fileUriPath)
put("mimeType", mimeType)
put("processedAt", timestamp)
put("aspectRatio", aspectRatio)
}

callback.invoke(fileData.toString())

} catch (e: Exception) {
callback.invoke(e.toString(), null)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.expensify.chat.intenthandler

import android.content.Context
import com.expensify.chat.utils.FileUtils.clearInternalStorageDirectory

abstract class AbstractIntentHandler: IntentHandler {
override fun onCompleted() {}

protected fun clearTemporaryFiles(context: Context) {
// Clear data present in the shared preferences
val sharedPreferences = context.getSharedPreferences(IntentHandlerConstants.preferencesFile, Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.clear()
editor.apply()

// Clear leftover temporary files from previous share attempts
clearInternalStorageDirectory(context)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.expensify.chat.intenthandler

import android.content.Context
import android.content.Intent
import android.net.Uri
import com.expensify.chat.utils.FileUtils

class FileIntentHandler(private val context: Context) : AbstractIntentHandler() {
override fun handle(intent: Intent): Boolean {
super.clearTemporaryFiles(context)
when(intent.action) {
Intent.ACTION_SEND -> {
handleSingleFileIntent(intent, context)
onCompleted()
return true
}
}
return false
}

private fun handleSingleFileIntent(intent: Intent, context: Context) {
(intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM))?.let { fileUri ->
val resultingPath: String? = FileUtils.copyUriToStorage(fileUri, context)

if (resultingPath != null) {
val shareFileObject = ShareFileObject(resultingPath, intent.type)

val sharedPreferences = context.getSharedPreferences(IntentHandlerConstants.preferencesFile, Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putString(IntentHandlerConstants.shareObjectProperty, shareFileObject.toString())
editor.apply()
}
}
}

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)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.expensify.chat.intenthandler

import android.content.Intent

object IntentHandlerConstants {
const val preferencesFile = "shareActionHandler"
const val shareObjectProperty = "shareObject"
}
interface IntentHandler {
fun handle(intent: Intent): Boolean
fun onCompleted()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.expensify.chat.intenthandler

import android.content.Context

object IntentHandlerFactory {
fun getIntentHandler(context: Context, mimeType: String?, rest: String?): IntentHandler? {
if (mimeType == null) return null

return when {
mimeType.matches(Regex("(image|application|audio|video)/.*")) -> FileIntentHandler(context)
mimeType.startsWith("text/") -> TextIntentHandler(context)
else -> throw UnsupportedOperationException("Unsupported MIME type: $mimeType")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.expensify.chat.intenthandler

import com.google.gson.Gson

data class ShareFileObject(val content: String, val mimeType: String?) {
override fun toString(): String {
return Gson().toJson(this)
Comment on lines +6 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add library for handling json for this line? Wouldn't it be easier just to do something like:

    override fun toString(): String {
        return "{\"content\": ${content}, \"mimeType\": ${mimeType}}"

Copy link
Contributor

@filip-solecki filip-solecki Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might work partially, but in case we don't want to add this library we have to handle a few more issues like escaping eg. Hello "world" is not a valid JSON string and we have to convert it to Hello \"world\" and there are more similar cases that need to be handled one by one

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what about using JSONObject from org.json.JSONObject like here

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.expensify.chat.intenthandler

import android.content.Context
import android.content.Intent
import android.net.Uri
import com.expensify.chat.utils.FileUtils


class TextIntentHandler(private val context: Context) : AbstractIntentHandler() {
override fun handle(intent: Intent): Boolean {
super.clearTemporaryFiles(context)
when(intent.action) {
Intent.ACTION_SEND -> {
handleTextIntent(intent, context)
onCompleted()
return true
}
}
return false
}

private fun handleTextIntent(intent: Intent, context: Context) {
when {
intent.type == "text/plain" -> {
val extras = intent.extras
if (extras != null) {
when {
extras.containsKey(Intent.EXTRA_STREAM) -> {
handleTextFileIntent(intent, context)
}
extras.containsKey(Intent.EXTRA_TEXT) -> {
handleTextPlainIntent(intent, context)
}
else -> {
throw UnsupportedOperationException("Unknown text/plain content")
}
}
}
}
Regex("text/.*").matches(intent.type ?: "") -> handleTextFileIntent(intent, context)
else -> throw UnsupportedOperationException("Unsupported MIME type: ${intent.type}")
}
}

private fun saveToSharedPreferences(key: String, value: String) {
val sharedPreferences = context.getSharedPreferences(IntentHandlerConstants.preferencesFile, Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putString(key, value)
editor.apply()
}

private fun handleTextFileIntent(intent: Intent, context: Context) {
(intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM))?.let { fileUri ->
val resultingPath: String? = FileUtils.copyUriToStorage(fileUri, context)
if (resultingPath != null) {
val shareFileObject = ShareFileObject(resultingPath, intent.type)
saveToSharedPreferences(IntentHandlerConstants.shareObjectProperty, shareFileObject.toString())
}
}
}

private fun handleTextPlainIntent(intent: Intent, context: Context) {
var intentTextContent = intent.getStringExtra(Intent.EXTRA_TEXT)
if(intentTextContent != null) {
val shareFileObject = ShareFileObject(intentTextContent, intent.type)
saveToSharedPreferences(IntentHandlerConstants.shareObjectProperty, shareFileObject.toString())
}
}

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)
}
}
Loading
Loading