diff --git a/.github/workflows/platformDeploy.yml b/.github/workflows/platformDeploy.yml index 608aa21204e1..5575d05609f2 100644 --- a/.github/workflows/platformDeploy.yml +++ b/.github/workflows/platformDeploy.yml @@ -209,13 +209,12 @@ jobs: max_attempts: 5 command: npm ci - - uses: actions/cache@v2 - with: - path: ios/Pods - key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} - - name: Install cocoapods - run: cd ios && pod install + uses: nick-invision/retry@7c68161adf97a48beb850a595b8784ec57a98cbb + with: + timeout_minutes: 10 + max_attempts: 5 + command: cd ios && pod install - name: Decrypt profile run: cd ios && gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output chat_expensify_appstore.mobileprovision chat_expensify_appstore.mobileprovision.gpg diff --git a/android/app/build.gradle b/android/app/build.gradle index 6536d77a4f38..1b16a06056ea 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,8 +152,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001016103 - versionName "1.1.61-3" + versionCode 1001016400 + versionName "1.1.64-0" } splits { abi { diff --git a/assets/images/avatars/fallback-avatar.svg b/assets/images/avatars/fallback-avatar.svg new file mode 100644 index 000000000000..dc1a1497cfe5 --- /dev/null +++ b/assets/images/avatars/fallback-avatar.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/images/avatars/fallback-workspace-avatar.svg b/assets/images/avatars/fallback-workspace-avatar.svg new file mode 100644 index 000000000000..ac2f58122a0f --- /dev/null +++ b/assets/images/avatars/fallback-workspace-avatar.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 11022248ac59..d96b4d1a572d 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.1.61 + 1.1.64 CFBundleSignature ???? CFBundleURLTypes @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.61.3 + 1.1.64.0 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index aeca405ac99a..cad8e15bb84d 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.1.61 + 1.1.64 CFBundleSignature ???? CFBundleVersion - 1.1.61.3 + 1.1.64.0 diff --git a/package-lock.json b/package-lock.json index f05b89eb37fb..5abbb23cd0a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-3", + "version": "1.1.64-0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e3974a4f014f..236bb9790632 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.61-3", + "version": "1.1.64-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.", diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 71ecd130ed9d..ff51d2c427b8 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -7,6 +7,7 @@ import Icon from './Icon'; import themeColors from '../styles/themes/default'; import CONST from '../CONST'; import * as StyleUtils from '../styles/StyleUtils'; +import * as Expensicons from './Icon/Expensicons'; const propTypes = { /** Source for the avatar. Can be a URL or an icon. */ @@ -23,6 +24,9 @@ const propTypes = { /** The fill color for the icon. Can be hex, rgb, rgba, or valid react-native named color such as 'red' or 'blue' */ fill: PropTypes.string, + + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ + fallbackIcon: PropTypes.func, }; const defaultProps = { @@ -31,9 +35,17 @@ const defaultProps = { containerStyles: [], size: CONST.AVATAR_SIZE.DEFAULT, fill: themeColors.icon, + fallbackIcon: Expensicons.FallbackAvatar, }; class Avatar extends PureComponent { + constructor(props) { + super(props); + this.state = { + imageError: false, + }; + } + render() { if (!this.props.source) { return null; @@ -45,13 +57,21 @@ class Avatar extends PureComponent { ]; const iconSize = StyleUtils.getAvatarSize(this.props.size); + return ( - { - _.isFunction(this.props.source) - ? - : - } + {_.isFunction(this.props.source) || this.state.imageError + ? ( + + ) + : ( + this.setState({imageError: true})} /> + )} ); } diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 02644c75fec2..2e0d4f3c8792 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -53,6 +53,9 @@ const propTypes = { /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ + fallbackIcon: PropTypes.func, + ...withLocalizePropTypes, }; @@ -65,6 +68,7 @@ const defaultProps = { isUsingDefaultAvatar: false, isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, + fallbackIcon: Expensicons.FallbackAvatar, }; class AvatarWithImagePicker extends React.Component { @@ -181,6 +185,8 @@ class AvatarWithImagePicker extends React.Component { containerStyles={styles.avatarLarge} imageStyles={[styles.avatarLarge, styles.alignSelfCenter]} source={this.props.avatarURL} + fallbackIcon={this.props.fallbackIcon} + size={this.props.size} /> ) : ( diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index 0db3ff1253ef..aa37769156e3 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -101,6 +101,7 @@ class AvatarWithIndicator extends PureComponent { diff --git a/src/components/Button.js b/src/components/Button.js index 85254d4c1e75..a315abc160fc 100644 --- a/src/components/Button.js +++ b/src/components/Button.js @@ -247,7 +247,7 @@ class Button extends Component { onPressOut={this.props.onPressOut} disabled={this.props.isLoading || this.props.isDisabled} style={[ - this.props.isDisabled ? styles.cursorDisabled : {}, + this.props.isDisabled ? {...styles.cursorDisabled, ...styles.noSelect} : {}, ...this.additionalStyles, ]} > diff --git a/src/components/ConfirmContent.js b/src/components/ConfirmContent.js index 78e01b756a61..164a21ce9a8e 100644 --- a/src/components/ConfirmContent.js +++ b/src/components/ConfirmContent.js @@ -76,7 +76,7 @@ const ConfirmContent = props => ( /> {props.shouldShowCancelButton && (