Skip to content

Commit 9ab3ebc

Browse files
Merge branch 'Expensify:main' into fix/ignore-scrolling-on-mobile-chorme-after-long-press
2 parents 4336e77 + d28cddf commit 9ab3ebc

280 files changed

Lines changed: 3912 additions & 5017 deletions

File tree

Some content is hidden

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

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ src/libs/SearchParser/searchParser.js
1515
src/libs/SearchParser/autocompleteParser.js
1616
help/_scripts/**
1717
Mobile-Expensify/**
18+
vendor

.eslintrc.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ module.exports = {
237237
selector: 'TSEnumDeclaration',
238238
message: "Please don't declare enums, use union types instead.",
239239
},
240+
241+
// These are the original rules from AirBnB's style guide, modified to allow for...of loops and for...in loops
242+
{
243+
selector: 'LabeledStatement',
244+
message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
245+
},
246+
{
247+
selector: 'WithStatement',
248+
message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize. It is also deprecated.',
249+
},
240250
],
241251
'no-restricted-properties': [
242252
'error',

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

Lines changed: 275 additions & 177 deletions
Large diffs are not rendered by default.

.github/workflows/deploy.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,10 +595,10 @@ jobs:
595595

596596
- name: 🚀 Create prerelease 🚀
597597
run: |
598-
gh release create ${{ needs.prep.outputs.APP_VERSION }} --repo ${{ github.repository }} --title ${{ needs.prep.outputs.APP_VERSION }} --generate-notes --prerelease --target staging
598+
gh release create ${{ needs.prep.outputs.APP_VERSION }}-staging --repo ${{ github.repository }} --title ${{ needs.prep.outputs.APP_VERSION }} --generate-notes --prerelease --verify-tag --target staging
599599
RETRIES=0
600600
MAX_RETRIES=10
601-
until [[ $(gh release view ${{ needs.prep.outputs.APP_VERSION }} --repo ${{ github.repository }}) || $RETRIES -ge $MAX_RETRIES ]]; do
601+
until [[ $(gh release view ${{ needs.prep.outputs.APP_VERSION }}-staging --repo ${{ github.repository }}) || $RETRIES -ge $MAX_RETRIES ]]; do
602602
echo "release not found, retrying $((MAX_RETRIES - RETRIES++)) times"
603603
sleep 1
604604
done
@@ -786,7 +786,7 @@ jobs:
786786
if: ${{ always() && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }}
787787
needs: [prep, android, desktop, ios, web, checkDeploymentSuccess, createPrerelease, finalizeRelease]
788788
with:
789-
version: ${{ needs.prep.outputs.APP_VERSION }}
789+
version: ${{ needs.prep.outputs.APP_VERSION }}${{ github.ref != 'refs/heads/production' && '-staging' || '' }}
790790
env: ${{ github.ref == 'refs/heads/production' && 'production' || 'staging' }}
791791
android: ${{ needs.android.result }}
792792
ios: ${{ needs.ios.result }}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Remote Build Android
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches-ignore: [staging, production]
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest-xl
14+
strategy:
15+
matrix:
16+
include:
17+
- project_root: ./
18+
variant: 'developmentDebug'
19+
20+
- project_root: Mobile-Expensify/
21+
variant: 'Debug'
22+
steps:
23+
- name: Checkout
24+
# v4
25+
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
26+
with:
27+
submodules: true
28+
token: ${{ secrets.OS_BOTIFY_TOKEN }}
29+
30+
- name: Setup Node
31+
uses: ./.github/actions/composite/setupNode
32+
33+
- name: RNEF Remote Build - Android
34+
uses: callstackincubator/android@a49920aadab9f41951944ea52bb7983fa6b20b03
35+
env:
36+
PROJECT_ROOT_PATH: ${{ matrix.project_root }}
37+
with:
38+
variant: ${{ matrix.variant }}
39+
github-token: ${{ github.token }}
40+
comment-bot: false
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Remote Build iOS
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches-ignore: [staging, production]
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
11+
jobs:
12+
build:
13+
runs-on: macos-15-xlarge
14+
strategy:
15+
matrix:
16+
include:
17+
- project_root: ./
18+
scheme: 'New Expensify Dev'
19+
configuration: 'DebugDevelopment'
20+
21+
- project_root: Mobile-Expensify/
22+
scheme: 'Expensify Dev'
23+
configuration: 'Debug'
24+
steps:
25+
- name: Checkout
26+
# v4
27+
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
28+
with:
29+
submodules: true
30+
token: ${{ secrets.OS_BOTIFY_TOKEN }}
31+
32+
- name: Setup Node
33+
uses: ./.github/actions/composite/setupNode
34+
35+
- name: RNEF Remote Build - iOS
36+
uses: callstackincubator/ios@4c2dcc0d6b9c35407cf294e17386b65258a3b6af
37+
env:
38+
PROJECT_ROOT_PATH: ${{ matrix.project_root }}
39+
with:
40+
destination: simulator
41+
scheme: ${{ matrix.scheme }}
42+
configuration: ${{ matrix.configuration }}
43+
github-token: ${{ github.token }}
44+
comment-bot: false

.storybook/main.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ const main: StorybookConfig = {
1414
name: '@storybook/react-webpack5',
1515
options: {},
1616
},
17-
docs: {
18-
autodocs: false,
19-
},
17+
docs: {},
2018
};
2119

2220
export default main;

Mobile-Expensify

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 1009012700
118-
versionName "9.1.27-0"
117+
versionCode 1009012702
118+
versionName "9.1.27-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"

desktop/main.ts

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ process.argv.forEach((arg) => {
128128
let hasUpdate = false;
129129
let downloadedVersion: string;
130130
let isSilentUpdating = false;
131+
let isUpdateInProgress = false;
131132

132133
// Note that we have to subscribe to this separately and cannot use translateLocal,
133134
// because the only way code can be shared between the main and renderer processes at runtime is via the context bridge
@@ -137,65 +138,119 @@ const preferredLocale: Locale = CONST.LOCALES.DEFAULT;
137138
const appProtocol = CONST.DEEPLINK_BASE_URL.replace('://', '');
138139

139140
const quitAndInstallWithUpdate = () => {
141+
console.debug('[dev] Attempting to quit and install update');
140142
if (!downloadedVersion) {
143+
console.debug('[dev] No downloaded version available, skipping quit and install');
141144
return;
142145
}
146+
console.debug(`[dev] Setting hasUpdate flag and installing version: ${downloadedVersion}`);
143147
hasUpdate = true;
144148
autoUpdater.quitAndInstall();
145149
};
146150

147-
const verifyAndInstallLatestVersion = (): void => {
151+
const verifyAndInstallLatestVersion = (browserWindow: BrowserWindow): void => {
152+
console.debug('[dev] Starting verifyAndInstallLatestVersion process');
153+
154+
if (!browserWindow || browserWindow.isDestroyed()) {
155+
console.debug('[dev] Browser window is invalid or destroyed, skipping update check');
156+
return;
157+
}
158+
159+
// Prevent multiple simultaneous updates
160+
if (isUpdateInProgress) {
161+
console.debug('[dev] Update already in progress, skipping new update check');
162+
return;
163+
}
164+
165+
console.debug('[dev] Setting isUpdateInProgress flag and starting update check');
166+
isUpdateInProgress = true;
167+
148168
autoUpdater
149169
.checkForUpdates()
150170
.then((result) => {
171+
console.debug('[dev] Update check completed', result?.updateInfo);
172+
173+
if (!browserWindow || browserWindow.isDestroyed()) {
174+
console.debug('[dev] Browser window became invalid during update check, aborting');
175+
isUpdateInProgress = false;
176+
return;
177+
}
178+
151179
if (result?.updateInfo.version === downloadedVersion) {
180+
console.debug(`[dev] Found matching version ${downloadedVersion}, proceeding with installation`);
152181
return quitAndInstallWithUpdate();
153182
}
154183

184+
console.debug('[dev] New version found, starting download');
155185
return autoUpdater.downloadUpdate().then(() => {
186+
console.debug('[dev] Download completed, proceeding with installation');
156187
return quitAndInstallWithUpdate();
157188
});
158189
})
159190
.catch((error) => {
191+
console.debug('[dev] Error during update check or download:', error);
160192
log.error('Error during update check or download:', error);
193+
})
194+
.finally(() => {
195+
console.debug('[dev] Update process completed, resetting isUpdateInProgress flag');
196+
isUpdateInProgress = false;
161197
});
162198
};
163199

164200
/** Menu Item callback to trigger an update check */
165201
const manuallyCheckForUpdates = (menuItem?: MenuItem, browserWindow?: BaseWindow) => {
202+
console.debug('[dev] Starting manual update check process');
203+
204+
// Prevent multiple simultaneous updates
205+
if (isUpdateInProgress) {
206+
console.debug('[dev] Update already in progress, skipping manual update check');
207+
return;
208+
}
209+
166210
if (menuItem) {
211+
console.debug('[dev] Disabling menu item during update check');
167212
// Disable item until the check (and download) is complete
168213
// eslint-disable-next-line no-param-reassign -- menu item flags like enabled or visible can be dynamically toggled by mutating the object
169214
menuItem.enabled = false;
170215
}
216+
217+
console.debug('[dev] Setting isUpdateInProgress flag and starting manual update check');
218+
isUpdateInProgress = true;
219+
171220
autoUpdater
172221
.checkForUpdates()
173222
.catch((error: unknown) => {
223+
console.debug('[dev] Error during manual update check:', error);
174224
isSilentUpdating = false;
175225
return {error};
176226
})
177227
.then((result) => {
228+
console.debug('[dev] Manual update check completed', result);
178229
const downloadPromise = result && 'downloadPromise' in result ? result.downloadPromise : undefined;
179230

180231
if (!browserWindow) {
232+
console.debug('[dev] No browser window available, skipping update dialogs');
181233
return;
182234
}
183235

184236
if (downloadPromise) {
237+
console.debug('[dev] Update available, showing info dialog');
185238
dialog.showMessageBox(browserWindow, {
186239
type: 'info',
187240
message: translate(preferredLocale, 'checkForUpdatesModal.available.title'),
188241
detail: translate(preferredLocale, 'checkForUpdatesModal.available.message', {isSilentUpdating}),
189242
buttons: [translate(preferredLocale, 'checkForUpdatesModal.available.soundsGood')],
190243
});
191244
} else if (result && 'error' in result && result.error) {
245+
console.debug('[dev] Update check failed, showing error dialog');
192246
dialog.showMessageBox(browserWindow, {
193247
type: 'error',
194248
message: translate(preferredLocale, 'checkForUpdatesModal.error.title'),
195249
detail: translate(preferredLocale, 'checkForUpdatesModal.error.message'),
196250
buttons: [translate(preferredLocale, 'checkForUpdatesModal.notAvailable.okay')],
197251
});
198252
} else {
253+
console.debug('[dev] No update available, showing info dialog');
199254
dialog.showMessageBox(browserWindow, {
200255
type: 'info',
201256
message: translate(preferredLocale, 'checkForUpdatesModal.notAvailable.title'),
@@ -209,10 +264,13 @@ const manuallyCheckForUpdates = (menuItem?: MenuItem, browserWindow?: BaseWindow
209264
return downloadPromise;
210265
})
211266
.finally(() => {
267+
console.debug('[dev] Manual update check completed, resetting flags');
212268
isSilentUpdating = false;
269+
isUpdateInProgress = false;
213270
if (!menuItem) {
214271
return;
215272
}
273+
console.debug('[dev] Re-enabling menu item');
216274
// eslint-disable-next-line no-param-reassign
217275
menuItem.enabled = true;
218276
});
@@ -245,12 +303,12 @@ const electronUpdater = (browserWindow: BrowserWindow): PlatformSpecificUpdater
245303
if (browserWindow.isVisible() && !isSilentUpdating) {
246304
browserWindow.webContents.send(ELECTRON_EVENTS.UPDATE_DOWNLOADED, info.version);
247305
} else {
248-
verifyAndInstallLatestVersion();
306+
verifyAndInstallLatestVersion(browserWindow);
249307
}
250308
});
251309

252310
ipcMain.on(ELECTRON_EVENTS.START_UPDATE, () => {
253-
verifyAndInstallLatestVersion();
311+
verifyAndInstallLatestVersion(browserWindow);
254312
});
255313
autoUpdater.checkForUpdates();
256314
},
@@ -398,7 +456,7 @@ const mainWindow = (): Promise<void> => {
398456
{
399457
id: 'update',
400458
label: translate(preferredLocale, `desktopApplicationMenu.update`),
401-
click: verifyAndInstallLatestVersion,
459+
click: () => verifyAndInstallLatestVersion(browserWindow),
402460
visible: false,
403461
},
404462
{id: 'checkForUpdates', label: translate(preferredLocale, `desktopApplicationMenu.checkForUpdates`), click: manuallyCheckForUpdates},
@@ -628,11 +686,21 @@ const mainWindow = (): Promise<void> => {
628686
});
629687

630688
app.on('before-quit', () => {
689+
console.debug('[dev] Application is preparing to quit');
631690
// Adding __DEV__ check because we want links to be handled by dev app only while it's running
632691
// https://github.com/Expensify/App/issues/15965#issuecomment-1483182952
633692
if (__DEV__) {
693+
console.debug('[dev] Removing protocol client in dev mode');
634694
app.removeAsDefaultProtocolClient(appProtocol);
635695
}
696+
697+
// Clean up update listeners and reset flags
698+
console.debug('[dev] Cleaning up update listeners and resetting flags');
699+
autoUpdater.removeAllListeners();
700+
isUpdateInProgress = false;
701+
isSilentUpdating = false;
702+
703+
console.debug('[dev] Setting quitting flag to true');
636704
quitting = true;
637705
});
638706
app.on('activate', () => {

0 commit comments

Comments
 (0)