Skip to content

Commit 82852f7

Browse files
committed
Merge branch 'main' into collectioneur/transition-tracker-eslint
2 parents 3e7180b + e69882b commit 82852f7

34 files changed

Lines changed: 424 additions & 138 deletions

Mobile-Expensify

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ android {
111111
minSdkVersion rootProject.ext.minSdkVersion
112112
targetSdkVersion rootProject.ext.targetSdkVersion
113113
multiDexEnabled rootProject.ext.multiDexEnabled
114-
versionCode 1009036401
115-
versionName "9.3.64-1"
114+
versionCode 1009036410
115+
versionName "9.3.64-10"
116116
// Supported language variants must be declared here to avoid from being removed during the compilation.
117117
// This also helps us to not include unnecessary language variants in the APK.
118118
resConfigs "en", "es"

ios/NewExpensify/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
</dict>
4545
</array>
4646
<key>CFBundleVersion</key>
47-
<string>9.3.64.1</string>
47+
<string>9.3.64.10</string>
4848
<key>FullStory</key>
4949
<dict>
5050
<key>OrgId</key>

ios/NotificationServiceExtension/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<key>CFBundleShortVersionString</key>
1414
<string>9.3.64</string>
1515
<key>CFBundleVersion</key>
16-
<string>9.3.64.1</string>
16+
<string>9.3.64.10</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionPointIdentifier</key>

ios/ShareViewController/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<key>CFBundleShortVersionString</key>
1414
<string>9.3.64</string>
1515
<key>CFBundleVersion</key>
16-
<string>9.3.64.1</string>
16+
<string>9.3.64.10</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionAttributes</key>

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "new.expensify",
3-
"version": "9.3.64-1",
3+
"version": "9.3.64-10",
44
"author": "Expensify, Inc.",
55
"homepage": "https://new.expensify.com",
66
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
diff --git a/node_modules/@shopify/flash-list/dist/recyclerview/RecyclerView.js b/node_modules/@shopify/flash-list/dist/recyclerview/RecyclerView.js
2+
index ee42f63..4e8d8c0 100644
3+
--- a/node_modules/@shopify/flash-list/dist/recyclerview/RecyclerView.js
4+
+++ b/node_modules/@shopify/flash-list/dist/recyclerview/RecyclerView.js
5+
@@ -380,16 +380,15 @@ const RecyclerViewComponent = (props, ref) => {
6+
}
7+
return onScrollHandler;
8+
}, [onScrollHandler, scrollY, stickyHeaders, stickyHeaderUseNativeDriver]);
9+
- const shouldMaintainVisibleContentPosition = recyclerViewManager.shouldMaintainVisibleContentPosition();
10+
const maintainVisibleContentPositionInternal = useMemo(() => {
11+
- if (shouldMaintainVisibleContentPosition) {
12+
+ if (maintainVisibleContentPosition != null) {
13+
return {
14+
...maintainVisibleContentPosition,
15+
minIndexForVisible: 0,
16+
};
17+
}
18+
return undefined;
19+
- }, [maintainVisibleContentPosition, shouldMaintainVisibleContentPosition]);
20+
+ }, [maintainVisibleContentPosition]);
21+
const shouldRenderFromBottom = recyclerViewManager.getDataLength() > 0 &&
22+
((_d = maintainVisibleContentPosition === null || maintainVisibleContentPosition === void 0 ? void 0 : maintainVisibleContentPosition.startRenderingFromBottom) !== null && _d !== void 0 ? _d : false);
23+
// Create view for measuring bounded size
24+
@@ -401,11 +399,11 @@ const RecyclerViewComponent = (props, ref) => {
25+
}, ref: firstChildViewRef }));
26+
}, [horizontal, stickyHeaderOffset]);
27+
const scrollAnchor = useMemo(() => {
28+
- if (shouldMaintainVisibleContentPosition) {
29+
+ if (maintainVisibleContentPosition != null) {
30+
return (React.createElement(ScrollAnchor, { horizontal: Boolean(horizontal), scrollAnchorRef: scrollAnchorRef }));
31+
}
32+
return null;
33+
- }, [horizontal, shouldMaintainVisibleContentPosition]);
34+
+ }, [horizontal, maintainVisibleContentPosition]);
35+
// console.log("render", recyclerViewManager.getRenderStack());
36+
// Render the main RecyclerView structure
37+
return (React.createElement(RecyclerViewContextProvider, { value: recyclerViewContext },
38+
diff --git a/node_modules/@shopify/flash-list/src/recyclerview/RecyclerView.tsx b/node_modules/@shopify/flash-list/src/recyclerview/RecyclerView.tsx
39+
index b2bd67a..d4bf02d 100644
40+
--- a/node_modules/@shopify/flash-list/src/recyclerview/RecyclerView.tsx
41+
+++ b/node_modules/@shopify/flash-list/src/recyclerview/RecyclerView.tsx
42+
@@ -572,18 +572,15 @@ const RecyclerViewComponent = <T,>(
43+
return onScrollHandler;
44+
}, [onScrollHandler, scrollY, stickyHeaders, stickyHeaderUseNativeDriver]);
45+
46+
- const shouldMaintainVisibleContentPosition =
47+
- recyclerViewManager.shouldMaintainVisibleContentPosition();
48+
-
49+
const maintainVisibleContentPositionInternal = useMemo(() => {
50+
- if (shouldMaintainVisibleContentPosition) {
51+
+ if (maintainVisibleContentPosition != null) {
52+
return {
53+
...maintainVisibleContentPosition,
54+
minIndexForVisible: 0,
55+
};
56+
}
57+
return undefined;
58+
- }, [maintainVisibleContentPosition, shouldMaintainVisibleContentPosition]);
59+
+ }, [maintainVisibleContentPosition]);
60+
61+
const shouldRenderFromBottom =
62+
recyclerViewManager.getDataLength() > 0 &&
63+
@@ -604,7 +600,7 @@ const RecyclerViewComponent = <T,>(
64+
}, [horizontal, stickyHeaderOffset]);
65+
66+
const scrollAnchor = useMemo(() => {
67+
- if (shouldMaintainVisibleContentPosition) {
68+
+ if (maintainVisibleContentPosition != null) {
69+
return (
70+
<ScrollAnchor
71+
horizontal={Boolean(horizontal)}
72+
@@ -613,7 +609,7 @@ const RecyclerViewComponent = <T,>(
73+
);
74+
}
75+
return null;
76+
- }, [horizontal, shouldMaintainVisibleContentPosition]);
77+
+ }, [horizontal, maintainVisibleContentPosition]);
78+
79+
// console.log("render", recyclerViewManager.getRenderStack());
80+

patches/@shopify/flash-list/details.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@
4848
- Upstream PR/issue: TBD
4949
- E/App issue: https://github.com/Expensify/App/issues/33725
5050
- PR introducing patch: https://github.com/Expensify/App/pull/85114
51+
52+
### [@shopify+flash-list+2.3.0+007+fix-scroll-anchor-unmount-on-ios.patch](@shopify+flash-list+2.3.0+007+fix-scroll-anchor-unmount-on-ios.patch)
53+
54+
- Reason: Fixes a scroll position reset on iOS when `maintainVisibleContentPosition.disabled` toggles from `true` to `false` (e.g. when `shouldMaintainVisibleContentPosition` changes based on scroll offset). Root cause: `ScrollAnchor` was conditionally rendered based on `shouldMaintainVisibleContentPosition()`. When MVCP was disabled, the anchor unmounted, which made the native Fabric `_firstVisibleView` weak-ref become nil. When MVCP was re-enabled, the anchor remounted at `top: 1,000,000` (its initial position), but `_prevFirstVisibleFrame` was stale at `1,000,000 + X` from the prior anchor instance. `_adjustForMaintainVisibleContentPosition` then computed `deltaY = 0 - (1,000,000 + X)` — a massive negative offset — causing the list to jump to the start. The fix decouples anchor lifetime from the `disabled` flag: `ScrollAnchor` is now always mounted (and `maintainVisibleContentPositionInternal` always non-null) whenever `maintainVisibleContentPosition` prop is defined. The `disabled` flag continues to gate JS-level `scrollBy` corrections in `applyOffsetCorrection` (via `shouldMaintainVisibleContentPosition()`), so the anchor stays in place when MVCP is logically off — the native side always has a live `_firstVisibleView` and a fresh `_prevFirstVisibleFrame` to diff against.
55+
- Files changed: Both `src/recyclerview/RecyclerView.tsx` and `dist/recyclerview/RecyclerView.js`.
56+
- Upstream PR/issue: TBD
57+
- E/App issue: https://github.com/Expensify/App/issues/33725
58+
- PR introducing patch: TBD

src/components/KYCWall/BaseKYCWall.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,14 @@ function KYCWall({
144144
if (iouReport && isIOUReport(iouReport)) {
145145
const adminPolicy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policy?.id}`];
146146
if (adminPolicy) {
147-
const inviteResult = moveIOUReportToPolicyAndInviteSubmitter(iouReport, adminPolicy, formatPhoneNumber, filteredReportActions, reportTransactions);
147+
const inviteResult = moveIOUReportToPolicyAndInviteSubmitter(
148+
iouReport,
149+
adminPolicy,
150+
formatPhoneNumber,
151+
filteredReportActions,
152+
currentUserAccountID,
153+
reportTransactions,
154+
);
148155
if (inviteResult?.policyExpenseChatReportID) {
149156
setNavigationActionToMicrotaskQueue(() => {
150157
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(inviteResult.policyExpenseChatReportID));

0 commit comments

Comments
 (0)