Skip to content

Commit 4cc68e7

Browse files
committed
Merge branch 'main' into @OlGierd03/correct-color-scroll-bar-in-help-panel
2 parents d11fc97 + 48a96b0 commit 4cc68e7

30 files changed

Lines changed: 282 additions & 69 deletions

Mobile-Expensify

contributingGuides/HOW_TO_BECOME_A_CONTRIBUTOR_PLUS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ C+ are contributors who are experienced at working with Expensify and have gaine
1313
- If C+ ever applies to work at Expensify, they’ve got a leg up on the competition because they're familiar with the company and processes. View job openings at https://we.are.expensify.com.
1414

1515
## Requirements to join C+
16-
- Have had 10 PRs deployed to production without regressions.
16+
- Have had 30 PRs deployed to production without regressions.
1717
- Follow our Code of Conduct, Contributing.md and README.md docs and processes.
1818
- Comment and fix bugs in a timely manner.
1919
- Clear communicator

ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2847,7 +2847,7 @@ PODS:
28472847
- RNGoogleSignin (10.0.1):
28482848
- GoogleSignIn (~> 7.0)
28492849
- React-Core
2850-
- RNLiveMarkdown (0.1.288):
2850+
- RNLiveMarkdown (0.1.294):
28512851
- DoubleConversion
28522852
- glog
28532853
- hermes-engine
@@ -3716,7 +3716,7 @@ SPEC CHECKSUMS:
37163716
AirshipServiceExtension: 9c73369f426396d9fb9ff222d86d842fac76ba46
37173717
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
37183718
AppLogs: 3bc4e9b141dbf265b9464409caaa40416a9ee0e0
3719-
boost: 659a89341ea4ab3df8259733813b52f26d8be9a5
3719+
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
37203720
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
37213721
EXAV: 13d43af15268a3f448a6b994e91574c939f065e6
37223722
EXImageLoader: ab4fcf9240cf3636a83c00e3fc5229d692899428
@@ -3867,7 +3867,7 @@ SPEC CHECKSUMS:
38673867
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
38683868
RNGestureHandler: 5d8431415d4b8518e86e289e9ad5bb9be78f6dba
38693869
RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0
3870-
RNLiveMarkdown: 1c09c5813366c29885b757b4c0a5e163a89f8d55
3870+
RNLiveMarkdown: 6e4972e95cf3b5ad0d164e08c72a6098d84e0b9d
38713871
RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81
38723872
rnmapbox-maps: ef00aafe2cbef8808f2aa6168e3f86ce103058bc
38733873
RNNitroSQLite: 44e596c1fb8f852f9a158eb07c647f706df13514

package-lock.json

Lines changed: 4 additions & 4 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
@@ -86,7 +86,7 @@
8686
"@expensify/nitro-utils": "file:./modules/ExpensifyNitroUtils",
8787
"@expensify/react-native-background-task": "file:./modules/background-task",
8888
"@expensify/react-native-hybrid-app": "file:./modules/hybrid-app",
89-
"@expensify/react-native-live-markdown": "0.1.289",
89+
"@expensify/react-native-live-markdown": "0.1.294",
9090
"@expensify/react-native-wallet": "^0.1.5",
9191
"@expo/metro-runtime": "^5.0.4",
9292
"@firebase/app": "^0.10.10",

patches/react-native/details.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,10 @@
176176
- Upstream PR/issue: 🛑
177177
- E/App issue: 🛑
178178
- PR Introducing Patch: https://github.com/Expensify/App/pull/60421
179+
180+
### [react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch](react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch)
181+
182+
- Reason: This patch updates Yoga to correctly update the subtrees of `display: contents` nodes so that they are in sync with their React Native counterparts.
183+
- Upstream PR/issue: https://github.com/facebook/react-native/pull/52530
184+
- E/App issue: https://github.com/Expensify/App/issues/65268
185+
- PR introducing patch: [#65925](https://github.com/Expensify/App/pull/65925)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp
2+
index 3618474..ab5b828 100644
3+
--- a/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp
4+
+++ b/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp
5+
@@ -476,16 +476,19 @@ static void zeroOutLayoutRecursively(yoga::Node* const node) {
6+
}
7+
8+
static void cleanupContentsNodesRecursively(yoga::Node* const node) {
9+
- for (auto child : node->getChildren()) {
10+
- if (child->style().display() == Display::Contents) {
11+
- child->getLayout() = {};
12+
- child->setLayoutDimension(0, Dimension::Width);
13+
- child->setLayoutDimension(0, Dimension::Height);
14+
- child->setHasNewLayout(true);
15+
- child->setDirty(false);
16+
- child->cloneChildrenIfNeeded();
17+
-
18+
- cleanupContentsNodesRecursively(child);
19+
+ if (node->hasContentsChildren()) [[unlikely]] {
20+
+ node->cloneContentsChildrenIfNeeded();
21+
+ for (auto child : node->getChildren()) {
22+
+ if (child->style().display() == Display::Contents) {
23+
+ child->getLayout() = {};
24+
+ child->setLayoutDimension(0, Dimension::Width);
25+
+ child->setLayoutDimension(0, Dimension::Height);
26+
+ child->setHasNewLayout(true);
27+
+ child->setDirty(false);
28+
+ child->cloneChildrenIfNeeded();
29+
+
30+
+ cleanupContentsNodesRecursively(child);
31+
+ }
32+
}
33+
}
34+
}
35+
diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp
36+
index dce42fb..f1bc5e8 100644
37+
--- a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp
38+
+++ b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp
39+
@@ -181,6 +181,17 @@ void Node::setDirty(bool isDirty) {
40+
}
41+
}
42+
43+
+void Node::setChildren(const std::vector<Node*>& children) {
44+
+ children_ = children;
45+
+
46+
+ contentsChildrenCount_ = 0;
47+
+ for (const auto& child : children) {
48+
+ if (child->style().display() == Display::Contents) {
49+
+ contentsChildrenCount_++;
50+
+ }
51+
+ }
52+
+}
53+
+
54+
bool Node::removeChild(Node* child) {
55+
auto p = std::find(children_.begin(), children_.end(), child);
56+
if (p != children_.end()) {
57+
@@ -379,6 +390,23 @@ void Node::cloneChildrenIfNeeded() {
58+
if (child->getOwner() != this) {
59+
child = resolveRef(config_->cloneNode(child, this, i));
60+
child->setOwner(this);
61+
+
62+
+ if (child->hasContentsChildren()) [[unlikely]] {
63+
+ child->cloneContentsChildrenIfNeeded();
64+
+ }
65+
+ }
66+
+ i += 1;
67+
+ }
68+
+}
69+
+
70+
+void Node::cloneContentsChildrenIfNeeded() {
71+
+ size_t i = 0;
72+
+ for (Node*& child : children_) {
73+
+ if (child->style().display() == Display::Contents &&
74+
+ child->getOwner() != this) {
75+
+ child = resolveRef(config_->cloneNode(child, this, i));
76+
+ child->setOwner(this);
77+
+ child->cloneChildrenIfNeeded();
78+
}
79+
i += 1;
80+
}
81+
diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h
82+
index 5ae7d43..3454d54 100644
83+
--- a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h
84+
+++ b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h
85+
@@ -96,6 +96,10 @@ class YG_EXPORT Node : public ::YGNode {
86+
return config_->hasErrata(errata);
87+
}
88+
89+
+ bool hasContentsChildren() const {
90+
+ return contentsChildrenCount_ != 0;
91+
+ }
92+
+
93+
YGDirtiedFunc getDirtiedFunc() const {
94+
return dirtiedFunc_;
95+
}
96+
@@ -244,15 +248,12 @@ class YG_EXPORT Node : public ::YGNode {
97+
owner_ = owner;
98+
}
99+
100+
- void setChildren(const std::vector<Node*>& children) {
101+
- children_ = children;
102+
- }
103+
-
104+
// TODO: rvalue override for setChildren
105+
106+
void setConfig(Config* config);
107+
108+
void setDirty(bool isDirty);
109+
+ void setChildren(const std::vector<Node*>& children);
110+
void setLayoutLastOwnerDirection(Direction direction);
111+
void setLayoutComputedFlexBasis(FloatOptional computedFlexBasis);
112+
void setLayoutComputedFlexBasisGeneration(
113+
@@ -286,6 +287,7 @@ class YG_EXPORT Node : public ::YGNode {
114+
void removeChild(size_t index);
115+
116+
void cloneChildrenIfNeeded();
117+
+ void cloneContentsChildrenIfNeeded();
118+
void markDirtyAndPropagate();
119+
float resolveFlexGrow() const;
120+
float resolveFlexShrink() const;

src/components/BrokenConnectionDescription.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function BrokenConnectionDescription({transactionID, policy, report}: BrokenConn
3939
return translate('violations.brokenConnection530Error');
4040
}
4141

42-
if (isPolicyAdmin && !isCurrentUserSubmitter(report?.reportID)) {
42+
if (isPolicyAdmin && !isCurrentUserSubmitter(report)) {
4343
return (
4444
<>
4545
{`${translate('violations.adminBrokenConnectionError')}`}

src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,10 @@ function MoneyRequestReportPreviewContent({
596596
}, [carouselTransactions.length]);
597597

598598
return (
599-
<View onLayout={onWrapperLayout}>
599+
<View
600+
onLayout={onWrapperLayout}
601+
testID="MoneyRequestReportPreviewContent-wrapper"
602+
>
600603
<OfflineWithFeedback
601604
pendingAction={iouReport?.pendingFields?.preview}
602605
shouldDisableOpacity={!!(action.pendingAction ?? action.isOptimisticAction)}

src/components/ReportActionItem/MoneyRequestReportPreview/index.tsx

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useCallback, useMemo, useState} from 'react';
1+
import React, {useCallback, useMemo, useRef, useState} from 'react';
22
import type {LayoutChangeEvent, ListRenderItem} from 'react-native';
33
import {usePersonalDetails} from '@components/OnyxListItemProvider';
44
import TransactionPreview from '@components/ReportActionItem/TransactionPreview';
@@ -52,11 +52,42 @@ function MoneyRequestReportPreview({
5252
const lastTransactionViolations = useTransactionViolations(lastTransaction?.transactionID);
5353
const isTrackExpenseAction = isTrackExpenseActionReportActionsUtils(action);
5454
const isSplitBillAction = isSplitBillActionReportActionsUtils(action);
55-
const [currentWidth, setCurrentWidth] = useState<number>(0);
56-
const [currentWrapperWidth, setCurrentWrapperWidth] = useState<number>(0);
55+
56+
const widthsRef = useRef<{currentWidth: number | null; currentWrapperWidth: number | null}>({currentWidth: null, currentWrapperWidth: null});
57+
const [widths, setWidths] = useState({currentWidth: 0, currentWrapperWidth: 0});
58+
59+
const updateWidths = useCallback(() => {
60+
const {currentWidth, currentWrapperWidth} = widthsRef.current;
61+
62+
if (currentWidth && currentWrapperWidth) {
63+
setWidths({currentWidth, currentWrapperWidth});
64+
}
65+
}, []);
66+
67+
const onCarouselLayout = useCallback(
68+
(e: LayoutChangeEvent) => {
69+
const newWidth = e.nativeEvent.layout.width;
70+
if (widthsRef.current.currentWidth !== newWidth) {
71+
widthsRef.current.currentWidth = newWidth;
72+
updateWidths();
73+
}
74+
},
75+
[updateWidths],
76+
);
77+
const onWrapperLayout = useCallback(
78+
(e: LayoutChangeEvent) => {
79+
const newWrapperWidth = e.nativeEvent.layout.width;
80+
if (widthsRef.current.currentWrapperWidth !== newWrapperWidth) {
81+
widthsRef.current.currentWrapperWidth = newWrapperWidth;
82+
updateWidths();
83+
}
84+
},
85+
[updateWidths],
86+
);
87+
5788
const reportPreviewStyles = useMemo(
58-
() => StyleUtils.getMoneyRequestReportPreviewStyle(shouldUseNarrowLayout, transactions.length, currentWidth, currentWrapperWidth),
59-
[StyleUtils, currentWidth, currentWrapperWidth, shouldUseNarrowLayout, transactions.length],
89+
() => StyleUtils.getMoneyRequestReportPreviewStyle(shouldUseNarrowLayout, transactions.length, widths.currentWidth, widths.currentWrapperWidth),
90+
[StyleUtils, widths, shouldUseNarrowLayout, transactions.length],
6091
);
6192
const shouldShowPayerAndReceiver = useMemo(() => {
6293
if (!isIOUReport(iouReport) && action.childType !== CONST.REPORT.TYPE.IOU) {
@@ -121,13 +152,9 @@ function MoneyRequestReportPreview({
121152
invoiceReceiverPolicy={invoiceReceiverPolicy}
122153
lastTransactionViolations={lastTransactionViolations}
123154
renderTransactionItem={renderItem}
124-
onCarouselLayout={(e: LayoutChangeEvent) => {
125-
setCurrentWidth(e.nativeEvent.layout.width);
126-
}}
127-
onWrapperLayout={(e: LayoutChangeEvent) => {
128-
setCurrentWrapperWidth(e.nativeEvent.layout.width);
129-
}}
130-
currentWidth={currentWidth}
155+
onCarouselLayout={onCarouselLayout}
156+
onWrapperLayout={onWrapperLayout}
157+
currentWidth={widths.currentWidth}
131158
reportPreviewStyles={reportPreviewStyles}
132159
shouldDisplayContextMenu={shouldDisplayContextMenu}
133160
isInvoice={isInvoice}

0 commit comments

Comments
 (0)