Skip to content

Commit

Permalink
Merge branch 'main' into ideal-nav-merge
Browse files Browse the repository at this point in the history
  • Loading branch information
adamgrzybowski committed Feb 1, 2024
2 parents f4611da + b636377 commit 45ec867
Show file tree
Hide file tree
Showing 101 changed files with 1,510 additions and 753 deletions.
16 changes: 5 additions & 11 deletions .github/actions/composite/buildAndroidE2EAPK/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,15 @@ runs:
- name: Append environment variables to env file
shell: bash
run: |
echo "EXPENSIFY_PARTNER_NAME=${EXPENSIFY_PARTNER_NAME}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_PASSWORD=${EXPENSIFY_PARTNER_PASSWORD}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_USER_ID=${EXPENSIFY_PARTNER_USER_ID}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_USER_SECRET=${EXPENSIFY_PARTNER_USER_SECRET}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_PASSWORD_EMAIL=${EXPENSIFY_PARTNER_PASSWORD_EMAIL}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_NAME=${{ inputs.EXPENSIFY_PARTNER_NAME }}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_PASSWORD=${{ inputs.EXPENSIFY_PARTNER_PASSWORD }}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_USER_ID=${{ inputs.EXPENSIFY_PARTNER_USER_ID }}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_USER_SECRET=${{ inputs.EXPENSIFY_PARTNER_USER_SECRET }}" >> ${{ inputs.PATH_ENV_FILE }}
echo "EXPENSIFY_PARTNER_PASSWORD_EMAIL=${{ inputs.EXPENSIFY_PARTNER_PASSWORD_EMAIL }}" >> ${{ inputs.PATH_ENV_FILE }}
- name: Build APK
run: npm run ${{ inputs.PACKAGE_SCRIPT_NAME }}
shell: bash
env:
EXPENSIFY_PARTNER_NAME: ${{ inputs.EXPENSIFY_PARTNER_NAME }}
EXPENSIFY_PARTNER_PASSWORD: ${{ inputs.EXPENSIFY_PARTNER_PASSWORD }}
EXPENSIFY_PARTNER_USER_ID: ${{ inputs.EXPENSIFY_PARTNER_USER_ID }}
EXPENSIFY_PARTNER_USER_SECRET: ${{ inputs.EXPENSIFY_PARTNER_USER_SECRET }}
EXPENSIFY_PARTNER_PASSWORD_EMAIL: ${{ inputs.EXPENSIFY_PARTNER_PASSWORD_EMAIL }}

- name: Upload APK
uses: actions/upload-artifact@65d862660abb392b8c4a3d1195a2108db131dd05
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001043400
versionName "1.4.34-0"
versionCode 1001043500
versionName "1.4.35-0"
}

flavorDimensions "default"
Expand Down
2 changes: 2 additions & 0 deletions docs/_includes/end-info.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
</div>
</div>
3 changes: 3 additions & 0 deletions docs/_includes/info.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="info">
<img src="/assets/images/info.svg" width="16" height="16">
<div markdown="1">
20 changes: 20 additions & 0 deletions docs/_sass/_main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,26 @@ button {
opacity: 0.8;
}
}

.info {
padding: 12px;
border-radius: 8px;
background-color: $color-highlightBG;
color: $color-text;
display: flex;
gap: 12px;
align-items: center;

img {
height: 16px;
width: 16px;
}

* {
padding: 0;
margin: 0;
}
}
}

}
Expand Down
21 changes: 21 additions & 0 deletions docs/articles/new-expensify/account-settings/Preferences.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Preferences
description: How to manage your Expensify Preferences
---
# Overview
Your Preferences in Expensify allow you to customize how you use New Expensify.

- Set your theme preference

# How to set your theme preference in New Expensify

To set or update your theme preference in New Expensify:
1. Go to **Settings > Preferences**
2. Tap on **Theme**
3. You can choose between the _Dark_ theme, the _Light_ theme, or _Use Device Settings_

_Use Device Settings_ is the default setting.

Selecting _Use Device Settings_ will use your device's theme settings. For example, if your device is set to adjust the appearance from light to dark during the day, we'll match that.

Your theme preference will sync across all your New Expensify apps (mobile, web, or OSX desktop apps).
9 changes: 9 additions & 0 deletions docs/assets/images/info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions docs/redirects.csv
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ https://community.expensify.com/discussion/6794/how-to-change-your-email-in-expe
https://help.expensify.com/articles/expensify-classic/expensify-card/Expensify-Card-Perks.html,https://use.expensify.com/company-credit-card
https://help.expensify.com/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.html,https://use.expensify.com/accountants-program
https://help.expensify.com/articles/expensify-classic/getting-started/approved-accountants/Card-Revenue-Share-For-Expensify-Approved-Partners, https://use.expensify.com/blog/maximizing-rewards-expensifyapproved-accounting-partners-now-earn-0-5-revenue-share
https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/International-Reimbursements,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/Global-Reimbursements
https://community.expensify.com/discussion/4452/how-to-merge-accounts,https://help.expensify.com/articles/expensify-classic/account-settings/Merge-Accounts#gsc.tab=0
https://community.expensify.com/discussion/4783/how-to-add-or-remove-a-copilot#latest,https://help.expensify.com/articles/expensify-classic/account-settings/Copilot#gsc.tab=0
https://community.expensify.com/discussion/4343/expensify-anz-partnership-announcement,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Connect-ANZ
https://community.expensify.com/discussion/7318/deep-dive-company-credit-card-import-options,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards
https://community.expensify.com/discussion/2673/personalize-your-commercial-card-feed-name,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Commercial-Card-Feeds
https://community.expensify.com/discussion/6569/how-to-import-and-assign-company-cards-from-csv-file,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/CSV-Import
https://community.expensify.com/discussion/4714/how-to-set-up-a-direct-bank-connection-for-company-cards,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Direct-Bank-Connections
https://community.expensify.com/discussion/4828/how-to-reconcile-your-company-cards-statement-in-expensify,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Reconciliation
https://community.expensify.com/discussion/5366/deep-dive-troubleshooting-credit-card-issues-in-expensify,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Troubleshooting
https://community.expensify.com/discussion/9554/how-to-set-up-global-reimbursemen,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/Global-Reimbursements
https://community.expensify.com/discussion/4463/how-to-remove-or-manage-settings-for-imported-personal-cards,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/Personal-Credit-Cards
https://community.expensify.com/discussion/5793/how-to-connect-your-personal-card-to-import-expenses,https://help.expensify.com/articles/expensify-classic/bank-accounts-and-credit-cards/Personal-Credit-Cards
https://community.expensify.com/discussion/4826/how-to-set-your-annual-subscription-size,https://help.expensify.com/articles/expensify-classic/billing-and-subscriptions/Annual-Subscription
https://community.expensify.com/discussion/5667/deep-dive-how-does-the-annual-subscription-billing-work,https://help.expensify.com/articles/expensify-classic/billing-and-subscriptions/Annual-Subscription
https://help.expensify.com/expensify-classic/hubs/getting-started/plan-types,https://www.expensify.com/pricing
4 changes: 2 additions & 2 deletions ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.4.34</string>
<string>1.4.35</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.4.34.0</string>
<string>1.4.35.0</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
4 changes: 2 additions & 2 deletions ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.4.34</string>
<string>1.4.35</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.34.0</string>
<string>1.4.35.0</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleShortVersionString</key>
<string>1.4.34</string>
<string>1.4.35</string>
<key>CFBundleVersion</key>
<string>1.4.34.0</string>
<string>1.4.35.0</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.4.34-0",
"version": "1.4.35-0",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
Expand Down
200 changes: 200 additions & 0 deletions patches/react-native-web+0.19.9+005+image-header-support.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
diff --git a/node_modules/react-native-web/dist/exports/Image/index.js b/node_modules/react-native-web/dist/exports/Image/index.js
index 95355d5..19109fc 100644
--- a/node_modules/react-native-web/dist/exports/Image/index.js
+++ b/node_modules/react-native-web/dist/exports/Image/index.js
@@ -135,7 +135,22 @@ function resolveAssetUri(source) {
}
return uri;
}
-var Image = /*#__PURE__*/React.forwardRef((props, ref) => {
+function raiseOnErrorEvent(uri, _ref) {
+ var onError = _ref.onError,
+ onLoadEnd = _ref.onLoadEnd;
+ if (onError) {
+ onError({
+ nativeEvent: {
+ error: "Failed to load resource " + uri + " (404)"
+ }
+ });
+ }
+ if (onLoadEnd) onLoadEnd();
+}
+function hasSourceDiff(a, b) {
+ return a.uri !== b.uri || JSON.stringify(a.headers) !== JSON.stringify(b.headers);
+}
+var BaseImage = /*#__PURE__*/React.forwardRef((props, ref) => {
var ariaLabel = props['aria-label'],
blurRadius = props.blurRadius,
defaultSource = props.defaultSource,
@@ -236,16 +251,10 @@ var Image = /*#__PURE__*/React.forwardRef((props, ref) => {
}
}, function error() {
updateState(ERRORED);
- if (onError) {
- onError({
- nativeEvent: {
- error: "Failed to load resource " + uri + " (404)"
- }
- });
- }
- if (onLoadEnd) {
- onLoadEnd();
- }
+ raiseOnErrorEvent(uri, {
+ onError,
+ onLoadEnd
+ });
});
}
function abortPendingRequest() {
@@ -277,10 +286,78 @@ var Image = /*#__PURE__*/React.forwardRef((props, ref) => {
suppressHydrationWarning: true
}), hiddenImage, createTintColorSVG(tintColor, filterRef.current));
});
-Image.displayName = 'Image';
+BaseImage.displayName = 'Image';
+
+/**
+ * This component handles specifically loading an image source with headers
+ * default source is never loaded using headers
+ */
+var ImageWithHeaders = /*#__PURE__*/React.forwardRef((props, ref) => {
+ // $FlowIgnore: This component would only be rendered when `source` matches `ImageSource`
+ var nextSource = props.source;
+ var _React$useState3 = React.useState(''),
+ blobUri = _React$useState3[0],
+ setBlobUri = _React$useState3[1];
+ var request = React.useRef({
+ cancel: () => {},
+ source: {
+ uri: '',
+ headers: {}
+ },
+ promise: Promise.resolve('')
+ });
+ var onError = props.onError,
+ onLoadStart = props.onLoadStart,
+ onLoadEnd = props.onLoadEnd;
+ React.useEffect(() => {
+ if (!hasSourceDiff(nextSource, request.current.source)) {
+ return;
+ }
+
+ // When source changes we want to clean up any old/running requests
+ request.current.cancel();
+ if (onLoadStart) {
+ onLoadStart();
+ }
+
+ // Store a ref for the current load request so we know what's the last loaded source,
+ // and so we can cancel it if a different source is passed through props
+ request.current = ImageLoader.loadWithHeaders(nextSource);
+ request.current.promise.then(uri => setBlobUri(uri)).catch(() => raiseOnErrorEvent(request.current.source.uri, {
+ onError,
+ onLoadEnd
+ }));
+ }, [nextSource, onLoadStart, onError, onLoadEnd]);
+
+ // Cancel any request on unmount
+ React.useEffect(() => request.current.cancel, []);
+ var propsToPass = _objectSpread(_objectSpread({}, props), {}, {
+ // `onLoadStart` is called from the current component
+ // We skip passing it down to prevent BaseImage raising it a 2nd time
+ onLoadStart: undefined,
+ // Until the current component resolves the request (using headers)
+ // we skip forwarding the source so the base component doesn't attempt
+ // to load the original source
+ source: blobUri ? _objectSpread(_objectSpread({}, nextSource), {}, {
+ uri: blobUri
+ }) : undefined
+ });
+ return /*#__PURE__*/React.createElement(BaseImage, _extends({
+ ref: ref
+ }, propsToPass));
+});

// $FlowIgnore: This is the correct type, but casting makes it unhappy since the variables aren't defined yet
-var ImageWithStatics = Image;
+var ImageWithStatics = /*#__PURE__*/React.forwardRef((props, ref) => {
+ if (props.source && props.source.headers) {
+ return /*#__PURE__*/React.createElement(ImageWithHeaders, _extends({
+ ref: ref
+ }, props));
+ }
+ return /*#__PURE__*/React.createElement(BaseImage, _extends({
+ ref: ref
+ }, props));
+});
ImageWithStatics.getSize = function (uri, success, failure) {
ImageLoader.getSize(uri, success, failure);
};
diff --git a/node_modules/react-native-web/dist/modules/ImageLoader/index.js b/node_modules/react-native-web/dist/modules/ImageLoader/index.js
index bc06a87..e309394 100644
--- a/node_modules/react-native-web/dist/modules/ImageLoader/index.js
+++ b/node_modules/react-native-web/dist/modules/ImageLoader/index.js
@@ -76,7 +76,7 @@ var ImageLoader = {
var image = requests["" + requestId];
if (image) {
var naturalHeight = image.naturalHeight,
- naturalWidth = image.naturalWidth;
+ naturalWidth = image.naturalWidth;
if (naturalHeight && naturalWidth) {
success(naturalWidth, naturalHeight);
complete = true;
@@ -102,11 +102,19 @@ var ImageLoader = {
id += 1;
var image = new window.Image();
image.onerror = onError;
- image.onload = e => {
+ image.onload = nativeEvent => {
// avoid blocking the main thread
- var onDecode = () => onLoad({
- nativeEvent: e
- });
+ var onDecode = () => {
+ // Append `source` to match RN's ImageLoadEvent interface
+ nativeEvent.source = {
+ uri: image.src,
+ width: image.naturalWidth,
+ height: image.naturalHeight
+ };
+ onLoad({
+ nativeEvent
+ });
+ };
if (typeof image.decode === 'function') {
// Safari currently throws exceptions when decoding svgs.
// We want to catch that error and allow the load handler
@@ -120,6 +128,32 @@ var ImageLoader = {
requests["" + id] = image;
return id;
},
+ loadWithHeaders(source) {
+ var uri;
+ var abortController = new AbortController();
+ var request = new Request(source.uri, {
+ headers: source.headers,
+ signal: abortController.signal
+ });
+ request.headers.append('accept', 'image/*');
+ var promise = fetch(request).then(response => response.blob()).then(blob => {
+ uri = URL.createObjectURL(blob);
+ return uri;
+ }).catch(error => {
+ if (error.name === 'AbortError') {
+ return '';
+ }
+ throw error;
+ });
+ return {
+ promise,
+ source,
+ cancel: () => {
+ abortController.abort();
+ URL.revokeObjectURL(uri);
+ }
+ };
+ },
prefetch(uri) {
return new Promise((resolve, reject) => {
ImageLoader.load(uri, () => {
Loading

0 comments on commit 45ec867

Please sign in to comment.