forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'vit-tieredBankAccountFlow' of github.com:barttom/App-ex…
…pensify into fix/more-styling-fixes
- Loading branch information
Showing
94 changed files
with
1,473 additions
and
760 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions
21
docs/articles/new-expensify/account-settings/Preferences.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
200 changes: 200 additions & 0 deletions
200
patches/react-native-web+0.19.9+005+image-header-support.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, () => { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.