Skip to content

Commit 22d2ff4

Browse files
authored
Merge branch 'main' into francois-beta-help-side-panel
2 parents 5081d73 + 4428d48 commit 22d2ff4

File tree

397 files changed

+14184
-9556
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

397 files changed

+14184
-9556
lines changed

.github/actions/javascript/authorChecklist/index.js

Lines changed: 1962 additions & 3026 deletions
Large diffs are not rendered by default.

.github/actions/javascript/bumpVersion/index.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,7 +3481,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
34813481
return (mod && mod.__esModule) ? mod : { "default": mod };
34823482
};
34833483
Object.defineProperty(exports, "__esModule", ({ value: true }));
3484-
exports.PLIST_PATH_TEST = exports.PLIST_PATH = exports.BUILD_GRADLE_PATH = exports.generateAndroidVersionCode = exports.updateAndroidVersion = exports.updateiOSVersion = void 0;
3484+
exports.PLIST_PATH = exports.BUILD_GRADLE_PATH = exports.generateAndroidVersionCode = exports.updateAndroidVersion = exports.updateiOSVersion = void 0;
34853485
const child_process_1 = __nccwpck_require__(2081);
34863486
const fs_1 = __nccwpck_require__(7147);
34873487
const path_1 = __importDefault(__nccwpck_require__(1017));
@@ -3494,8 +3494,6 @@ const BUILD_GRADLE_PATH = process.env.NODE_ENV === 'test' ? path_1.default.resol
34943494
exports.BUILD_GRADLE_PATH = BUILD_GRADLE_PATH;
34953495
const PLIST_PATH = './ios/NewExpensify/Info.plist';
34963496
exports.PLIST_PATH = PLIST_PATH;
3497-
const PLIST_PATH_TEST = './ios/NewExpensifyTests/Info.plist';
3498-
exports.PLIST_PATH_TEST = PLIST_PATH_TEST;
34993497
const PLIST_PATH_NSE = './ios/NotificationServiceExtension/Info.plist';
35003498
/**
35013499
* Pad a number to be two digits (with leading zeros if necessary).
@@ -3541,10 +3539,8 @@ function updateiOSVersion(version) {
35413539
console.log('Updating iOS', `CFBundleShortVersionString: ${shortVersion}`, `CFBundleVersion: ${cfVersion}`);
35423540
// Update Plists
35433541
(0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH}`);
3544-
(0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_TEST}`);
35453542
(0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_NSE}`);
35463543
(0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH}`);
3547-
(0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_TEST}`);
35483544
(0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_NSE}`);
35493545
// Return the cfVersion so we can set the NEW_IOS_VERSION in ios.yml
35503546
return cfVersion;

.github/libs/nativeVersionUpdater.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import getBuildVersion from 'semver/functions/prerelease';
1010
// Filepath constants
1111
const BUILD_GRADLE_PATH = process.env.NODE_ENV === 'test' ? path.resolve(__dirname, '../../android/app/build.gradle') : './android/app/build.gradle';
1212
const PLIST_PATH = './ios/NewExpensify/Info.plist';
13-
const PLIST_PATH_TEST = './ios/NewExpensifyTests/Info.plist';
1413
const PLIST_PATH_NSE = './ios/NotificationServiceExtension/Info.plist';
1514

1615
/**
@@ -65,14 +64,12 @@ function updateiOSVersion(version: string): string {
6564

6665
// Update Plists
6766
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH}`);
68-
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_TEST}`);
6967
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_NSE}`);
7068
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH}`);
71-
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_TEST}`);
7269
execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_NSE}`);
7370

7471
// Return the cfVersion so we can set the NEW_IOS_VERSION in ios.yml
7572
return cfVersion;
7673
}
7774

78-
export {updateiOSVersion, updateAndroidVersion, generateAndroidVersionCode, BUILD_GRADLE_PATH, PLIST_PATH, PLIST_PATH_TEST};
75+
export {updateiOSVersion, updateAndroidVersion, generateAndroidVersionCode, BUILD_GRADLE_PATH, PLIST_PATH};

.github/workflows/createNewVersion.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ jobs:
143143
./package-lock.json \
144144
./android/app/build.gradle \
145145
./ios/NewExpensify/Info.plist \
146-
./ios/NewExpensifyTests/Info.plist \
147146
./ios/NotificationServiceExtension/Info.plist
148147
git commit -m "Update version to ${{ steps.bumpVersion.outputs.NEW_VERSION }}"
149148

.github/workflows/deploy.yml

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66

77
env:
88
SHOULD_DEPLOY_PRODUCTION: ${{ github.ref == 'refs/heads/production' }}
9+
IS_APP_REPO: ${{ github.repository == 'Expensify/App' }}
910

1011
concurrency:
1112
group: ${{ github.workflow }}-${{ github.ref }}
@@ -185,12 +186,14 @@ jobs:
185186
ANDROID_UPLOAD_KEYSTORE_PASSWORD: ${{ steps.load-credentials.outputs.ANDROID_UPLOAD_KEYSTORE_PASSWORD }}
186187
ANDROID_UPLOAD_KEYSTORE_ALIAS: ${{ steps.load-credentials.outputs.ANDROID_UPLOAD_KEYSTORE_ALIAS }}
187188
ANDROID_UPLOAD_KEY_PASSWORD: ${{ steps.load-credentials.outputs.ANDROID_UPLOAD_KEY_PASSWORD }}
189+
ANDROID_BUILD_TYPE: ${{ vars.ANDROID_BUILD_TYPE }}
188190

189191
- name: Upload Android app to Google Play
190192
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
191-
run: bundle exec fastlane android upload_google_play_internal_hybrid
193+
run: bundle exec fastlane android ${{ vars.ANDROID_UPLOAD_COMMAND }}
192194
env:
193195
VERSION: ${{ steps.getAndroidVersion.outputs.VERSION_CODE }}
196+
ANDROID_PACKAGE_NAME: ${{ vars.ANDROID_PACKAGE_NAME }}
194197

195198
- name: Get current Android rollout percentage
196199
if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
@@ -217,7 +220,7 @@ jobs:
217220
VERSION: ${{ steps.getAndroidVersion.outputs.VERSION_CODE }}
218221

219222
- name: Upload Android build to Browser Stack
220-
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
223+
if: ${{ fromJSON(env.IS_APP_REPO) && !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
221224
run: curl -u "$BROWSERSTACK" -X POST "https://api-cloud.browserstack.com/app-live/upload" -F "file=@${{ env.aabPath }}"
222225
env:
223226
BROWSERSTACK: ${{ secrets.BROWSERSTACK }}
@@ -401,6 +404,10 @@ jobs:
401404
APPLE_DEMO_EMAIL: ${{ secrets.APPLE_DEMO_EMAIL }}
402405
APPLE_DEMO_PASSWORD: ${{ secrets.APPLE_DEMO_PASSWORD }}
403406

407+
- name: Upload DSYMs to Firebase
408+
if: ${{ fromJSON(env.IS_APP_REPO) && !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
409+
run: bundle exec fastlane ios upload_dsyms
410+
404411
- name: Upload iOS build to Browser Stack
405412
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
406413
run: curl -u "$BROWSERSTACK" -X POST "https://api-cloud.browserstack.com/app-live/upload" -F "file=@/Users/runner/work/App/App/New Expensify.ipa"
@@ -503,9 +510,9 @@ jobs:
503510
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
504511
run: |
505512
op read "op://${{ vars.OP_VAULT }}/firebase.json/firebase.json" --force --out-file ./firebase.json
506-
op read "op://${{ vars.OP_VAULT }}/OldApp_AppStore/OldApp_AppStore.mobileprovision" --force --out-file ./OldApp_AppStore.mobileprovision
507-
op read "op://${{ vars.OP_VAULT }}/OldApp_AppStore_Share_Extension/OldApp_AppStore_Share_Extension.mobileprovision" --force --out-file ./OldApp_AppStore_Share_Extension.mobileprovision
508-
op read "op://${{ vars.OP_VAULT }}/OldApp_AppStore_Notification_Service/OldApp_AppStore_Notification_Service.mobileprovision" --force --out-file ./OldApp_AppStore_Notification_Service.mobileprovision
513+
op read "op://${{ vars.OP_VAULT }}/OldApp_AppStore/${{ vars.APPLE_STORE_PROVISIONING_PROFILE_FILE }}" --force --out-file ./${{ vars.APPLE_STORE_PROVISIONING_PROFILE_FILE }}
514+
op read "op://${{ vars.OP_VAULT }}/OldApp_AppStore_Share_Extension/${{ vars.APPLE_SHARE_PROVISIONING_PROFILE_FILE }}" --force --out-file ./${{ vars.APPLE_SHARE_PROVISIONING_PROFILE_FILE }}
515+
op read "op://${{ vars.OP_VAULT }}/OldApp_AppStore_Notification_Service/${{ vars.APPLE_NOTIFICATION_PROVISIONING_PROFILE_FILE }}" --force --out-file ./${{ vars.APPLE_NOTIFICATION_PROVISIONING_PROFILE_FILE }}
509516
op read "op://${{ vars.OP_VAULT }}/ios-fastlane-json-key.json/ios-fastlane-json-key.json" --force --out-file ./ios-fastlane-json-key.json
510517
op read "op://${{ vars.OP_VAULT }}/New Expensify Distribution Certificate/Certificates.p12" --force --out-file ./Certificates.p12
511518
@@ -519,6 +526,14 @@ jobs:
519526
- name: Build iOS HybridApp
520527
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
521528
run: bundle exec fastlane ios build_hybrid
529+
env:
530+
APPLE_ID: ${{ vars.APPLE_ID }}
531+
APPLE_STORE_PROVISIONING_PROFILE_FILE: ${{ vars.APPLE_STORE_PROVISIONING_PROFILE_FILE }}
532+
APPLE_STORE_PROVISIONING_PROFILE_NAME: ${{ vars.APPLE_STORE_PROVISIONING_PROFILE_NAME }}
533+
APPLE_SHARE_PROVISIONING_PROFILE_FILE: ${{ vars.APPLE_SHARE_PROVISIONING_PROFILE_FILE }}
534+
APPLE_SHARE_PROVISIONING_PROFILE_NAME: ${{ vars.APPLE_SHARE_PROVISIONING_PROFILE_NAME }}
535+
APPLE_NOTIFICATION_PROVISIONING_PROFILE_FILE: ${{ vars.APPLE_NOTIFICATION_PROVISIONING_PROFILE_FILE }}
536+
APPLE_NOTIFICATION_PROVISIONING_PROFILE_NAME: ${{ vars.APPLE_NOTIFICATION_PROVISIONING_PROFILE_NAME }}
522537

523538
- name: Upload release build to TestFlight
524539
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
@@ -528,6 +543,11 @@ jobs:
528543
APPLE_CONTACT_PHONE: ${{ secrets.APPLE_CONTACT_PHONE }}
529544
APPLE_DEMO_EMAIL: ${{ secrets.APPLE_DEMO_EMAIL }}
530545
APPLE_DEMO_PASSWORD: ${{ secrets.APPLE_DEMO_PASSWORD }}
546+
APPLE_ID: ${{ vars.APPLE_ID }}
547+
548+
- name: Upload DSYMs to Firebase for HybridApp
549+
if: ${{ fromJSON(env.IS_APP_REPO) && !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
550+
run: bundle exec fastlane ios upload_dsyms_hybrid
531551

532552
- name: Submit production build for App Store review and a slow rollout
533553
if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
@@ -539,9 +559,10 @@ jobs:
539559
bundle exec fastlane ios submit_hybrid_for_rollout
540560
env:
541561
VERSION: ${{ steps.getIOSVersion.outputs.IOS_VERSION }}
562+
APPLE_ID: ${{ vars.APPLE_ID }}
542563

543564
- name: Upload iOS build to Browser Stack
544-
if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
565+
if: ${{ fromJSON(env.IS_APP_REPO) && !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }}
545566
run: curl -u "$BROWSERSTACK" -X POST "https://api-cloud.browserstack.com/app-live/upload" -F "file=@${{ env.ipaPath }}"
546567
env:
547568
BROWSERSTACK: ${{ secrets.BROWSERSTACK }}

Mobile-Expensify

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ You can only build HybridApp if you have been granted access to [`Mobile-Expensi
471471
ignore = all
472472
```
473473
This ensures that submodule changes are ignored unless you deliberately update them.
474+
3. Run `git config --global submodule.recurse true` in order to have the submodule updated when you pull App
474475

475476

476477
> [!Note]

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ android {
114114
minSdkVersion rootProject.ext.minSdkVersion
115115
targetSdkVersion rootProject.ext.targetSdkVersion
116116
multiDexEnabled rootProject.ext.multiDexEnabled
117-
versionCode 1009011509
118-
versionName "9.1.15-9"
117+
versionCode 1009011802
118+
versionName "9.1.18-2"
119119
// Supported language variants must be declared here to avoid from being removed during the compilation.
120120
// This also helps us to not include unnecessary language variants in the APK.
121121
resConfigs "en", "es"

android/app/src/main/AndroidManifest.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,52 @@
104104
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/track-expense"/>
105105
<data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/submit-expense"/>
106106
</intent-filter>
107+
<intent-filter>
108+
<action android:name="android.intent.action.SEND" />
109+
<category android:name="android.intent.category.DEFAULT" />
110+
111+
<!-- Images -->
112+
<data android:mimeType="image/jpg" />
113+
<data android:mimeType="image/jpeg" />
114+
<data android:mimeType="image/gif" />
115+
<data android:mimeType="image/png" />
116+
<data android:mimeType="image/tif" />
117+
<data android:mimeType="image/tiff" />
118+
119+
<!-- Documents -->
120+
<data android:mimeType="application/pdf" />
121+
<data android:mimeType="application/msword" />
122+
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
123+
<data android:mimeType="application/rtf" />
124+
<data android:mimeType="application/zip" />
125+
<data android:mimeType="message/rfc822" />
126+
127+
<!-- Text / HTML -->
128+
<data android:mimeType="text/plain" />
129+
<data android:mimeType="text/html" />
130+
<data android:mimeType="text/xml" />
131+
132+
<!-- Audio / Video -->
133+
<data android:mimeType="audio/mpeg" />
134+
<data android:mimeType="audio/aac" />
135+
<data android:mimeType="audio/flac" />
136+
<data android:mimeType="audio/wav" />
137+
<data android:mimeType="audio/x-wav" />
138+
<data android:mimeType="audio/mp3" />
139+
<data android:mimeType="audio/vorbis" />
140+
<data android:mimeType="audio/x-vorbis" />
141+
<data android:mimeType="audio/opus" />
142+
143+
<data android:mimeType="video/mp4" />
144+
<data android:mimeType="video/mp2t" />
145+
<data android:mimeType="video/webm" />
146+
<data android:mimeType="video/avc" />
147+
<data android:mimeType="video/hevc" />
148+
<data android:mimeType="video/x-vnd.on2.vp8" />
149+
<data android:mimeType="video/x-vnd.on2.vp9" />
150+
<data android:mimeType="video/av01" />
151+
152+
</intent-filter>
107153
</activity>
108154

109155
<meta-data

android/app/src/main/java/com/expensify/chat/ExpensifyAppPackage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public List<NativeModule> createNativeModules(
2222
List<NativeModule> modules = new ArrayList<>();
2323

2424
modules.add(new StartupTimer(reactContext));
25+
modules.add(new ShareActionHandlerModule(reactContext));
2526

2627
return modules;
2728
}

android/app/src/main/java/com/expensify/chat/MainActivity.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
package com.expensify.chat
22

3-
import expo.modules.ReactActivityDelegateWrapper
4-
3+
import android.content.Intent
54
import android.content.pm.ActivityInfo
65
import android.os.Bundle
6+
import android.util.Log
77
import android.view.KeyEvent
88
import android.view.View
99
import android.view.WindowInsets
1010
import com.expensify.chat.bootsplash.BootSplash
11+
import com.expensify.chat.intenthandler.IntentHandlerFactory
1112
import com.expensify.reactnativekeycommand.KeyCommandModule
1213
import com.facebook.react.ReactActivity
1314
import com.facebook.react.ReactActivityDelegate
1415
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
1516
import com.facebook.react.defaults.DefaultReactActivityDelegate
17+
import expo.modules.ReactActivityDelegateWrapper
1618

1719
import com.oblador.performance.RNPerformance
1820

@@ -52,6 +54,25 @@ class MainActivity : ReactActivity() {
5254
defaultInsets.systemWindowInsetBottom
5355
)
5456
}
57+
58+
if (intent != null) {
59+
handleIntent(intent)
60+
}
61+
}
62+
63+
override fun onNewIntent(intent: Intent) {
64+
super.onNewIntent(intent)
65+
setIntent(intent) // Must store the new intent unless getIntent() will return the old one
66+
handleIntent(intent)
67+
}
68+
69+
private fun handleIntent(intent: Intent) {
70+
try {
71+
val intenthandler = IntentHandlerFactory.getIntentHandler(this, intent.type, intent.toString())
72+
intenthandler?.handle(intent)
73+
} catch (exception: Exception) {
74+
Log.e("handleIntentException", exception.toString())
75+
}
5576
}
5677

5778
/**
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.expensify.chat
2+
3+
import android.content.Context
4+
import android.graphics.BitmapFactory
5+
import android.media.MediaMetadataRetriever
6+
import com.expensify.chat.intenthandler.IntentHandlerConstants
7+
import com.facebook.react.bridge.Callback
8+
import com.facebook.react.bridge.ReactApplicationContext
9+
import com.facebook.react.bridge.ReactContextBaseJavaModule
10+
import android.util.Log
11+
import com.facebook.react.bridge.ReactMethod
12+
import org.json.JSONObject
13+
import java.io.File
14+
15+
class ShareActionHandlerModule(reactContext: ReactApplicationContext) :
16+
ReactContextBaseJavaModule(reactContext) {
17+
18+
override fun getName(): String {
19+
return "ShareActionHandler"
20+
}
21+
22+
@ReactMethod
23+
fun processFiles(callback: Callback) {
24+
try {
25+
val sharedPreferences = reactApplicationContext.getSharedPreferences(
26+
IntentHandlerConstants.preferencesFile,
27+
Context.MODE_PRIVATE
28+
)
29+
30+
val shareObjectString = sharedPreferences.getString(IntentHandlerConstants.shareObjectProperty, null)
31+
if (shareObjectString == null) {
32+
callback.invoke("No data found", null)
33+
return
34+
}
35+
36+
val shareObject = JSONObject(shareObjectString)
37+
val content = shareObject.optString("content")
38+
val mimeType = shareObject.optString("mimeType")
39+
val fileUriPath = "file://$content"
40+
val timestamp = System.currentTimeMillis()
41+
42+
val file = File(content)
43+
if (!file.exists()) {
44+
val textObject = JSONObject().apply {
45+
put("id", "text")
46+
put("content", content)
47+
put("mimeType", "txt")
48+
put("processedAt", timestamp)
49+
}
50+
callback.invoke(textObject.toString())
51+
return
52+
}
53+
54+
val identifier = file.name
55+
var aspectRatio = 0.0f
56+
57+
if (mimeType.startsWith("image/")) {
58+
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
59+
BitmapFactory.decodeFile(content, options)
60+
aspectRatio = if (options.outHeight != 0) options.outWidth.toFloat() / options.outHeight else 1.0f
61+
} else if (mimeType.startsWith("video/")) {
62+
val retriever = MediaMetadataRetriever()
63+
try {
64+
retriever.setDataSource(content)
65+
val videoWidth = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toFloatOrNull() ?: 1f
66+
val videoHeight = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toFloatOrNull() ?: 1f
67+
if (videoHeight != 0f) aspectRatio = videoWidth / videoHeight
68+
} catch (e: Exception) {
69+
Log.e("ShareActionHandlerModule", "Error retrieving video metadata: ${e.message}")
70+
} finally {
71+
retriever.release()
72+
}
73+
}
74+
75+
val fileData = JSONObject().apply {
76+
put("id", identifier)
77+
put("content", fileUriPath)
78+
put("mimeType", mimeType)
79+
put("processedAt", timestamp)
80+
put("aspectRatio", aspectRatio)
81+
}
82+
83+
callback.invoke(fileData.toString())
84+
85+
} catch (e: Exception) {
86+
callback.invoke(e.toString(), null)
87+
}
88+
}
89+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.expensify.chat.intenthandler
2+
3+
import android.content.Context
4+
import com.expensify.chat.utils.FileUtils.clearInternalStorageDirectory
5+
6+
abstract class AbstractIntentHandler: IntentHandler {
7+
override fun onCompleted() {}
8+
9+
protected fun clearTemporaryFiles(context: Context) {
10+
// Clear data present in the shared preferences
11+
val sharedPreferences = context.getSharedPreferences(IntentHandlerConstants.preferencesFile, Context.MODE_PRIVATE)
12+
val editor = sharedPreferences.edit()
13+
editor.clear()
14+
editor.apply()
15+
16+
// Clear leftover temporary files from previous share attempts
17+
clearInternalStorageDirectory(context)
18+
}
19+
}

0 commit comments

Comments
 (0)