Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update version to 1.0.51-1 on staging #3075

Merged
merged 18 commits into from
May 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001005100
versionName "1.0.51-0"
versionCode 1001005101
versionName "1.0.51-1"
}
splits {
abi {
Expand Down
4 changes: 4 additions & 0 deletions assets/images/sync.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion ios/ExpensifyCash/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.0.51.0</string>
<string>1.0.51.1</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/ExpensifyCashTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.51.0</string>
<string>1.0.51.1</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion 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": "expensify.cash",
"version": "1.0.51-0",
"version": "1.0.51-1",
"author": "Expensify, Inc.",
"homepage": "https://expensify.cash",
"description": "Expensify.cash is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
Expand Down
151 changes: 126 additions & 25 deletions src/components/AvatarWithIndicator.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React, {memo} from 'react';
import {View, StyleSheet} from 'react-native';
import React, {PureComponent} from 'react';
import {
View, StyleSheet, Animated, Easing,
} from 'react-native';
import PropTypes from 'prop-types';
import Avatar from './Avatar';
import themeColors from '../styles/themes/default';
import styles from '../styles/styles';
import Icon from './Icon';
import {Sync} from './Icon/Expensicons';
import {getSyncingStyles} from '../styles/getAvatarWithIndicatorStyles';

const propTypes = {
/** Is user active? */
Expand All @@ -13,37 +19,132 @@ const propTypes = {

/** Avatar size */
size: PropTypes.string,

// Whether we show the sync indicator
isSyncing: PropTypes.bool,
};

const defaultProps = {
isActive: false,
size: 'default',
isSyncing: false,
};

const AvatarWithIndicator = ({
isActive,
source,
size,
}) => {
const indicatorStyles = [
size === 'large' ? styles.statusIndicatorLarge : styles.statusIndicator,
isActive ? styles.statusIndicatorOnline : styles.statusIndicatorOffline,
];

return (
<View
style={[size === 'large' ? styles.avatarLarge : styles.sidebarAvatar]}
>
<Avatar
style={[size === 'large' ? styles.avatarLarge : null]}
source={source}
/>
<View style={StyleSheet.flatten(indicatorStyles)} />
</View>
);
};
class AvatarWithIndicator extends PureComponent {
constructor(props) {
super(props);

this.rotate = new Animated.Value(0);
this.scale = new Animated.Value(1);
this.startRotation = this.startRotation.bind(this);
this.startSyncIndicator = this.startSyncIndicator.bind(this);
this.stopSyncIndicator = this.stopSyncIndicator.bind(this);
}

componentDidMount() {
if (this.props.isSyncing) {
this.startSyncIndicator();
}
}

componentDidUpdate(prevProps) {
if (!prevProps.isSyncing && this.props.isSyncing) {
this.startSyncIndicator();
} else if (prevProps.isSyncing && !this.props.isSyncing) {
this.stopSyncIndicator();
}
}

componentWillUnmount() {
this.stopSyncIndicator();
}

/**
* We need to manually loop the animations as `useNativeDriver` does not work well with Animated.loop.
*
* @memberof AvatarWithIndicator
*/
startRotation() {
this.rotate.setValue(0);
Animated.timing(this.rotate, {
toValue: 1,
duration: 2000,
easing: Easing.linear,
isInteraction: false,
useNativeDriver: true,
}).start(({finished}) => {
if (finished) {
this.startRotation();
}
});
}

/**
* Start Animation for Indicator
*
* @memberof AvatarWithIndicator
*/
startSyncIndicator() {
this.startRotation();
Animated.spring(this.scale, {
toValue: 1.666,
tension: 1,
isInteraction: false,
useNativeDriver: true,
}).start();
}

/**
* Stop Animation for Indicator
*
* @memberof AvatarWithIndicator
*/
stopSyncIndicator() {
Animated.spring(this.scale, {
toValue: 1,
tension: 1,
isInteraction: false,
useNativeDriver: true,
}).start(() => {
this.rotate.resetAnimation();
this.scale.resetAnimation();
this.rotate.setValue(0);
});
}

render() {
const indicatorStyles = [
styles.alignItemsCenter,
styles.justifyContentCenter,
this.props.size === 'large' ? styles.statusIndicatorLarge : styles.statusIndicator,
this.props.isActive ? styles.statusIndicatorOnline : styles.statusIndicatorOffline,
getSyncingStyles(this.rotate, this.scale),
];

return (
<View
style={[this.props.size === 'large' ? styles.avatarLarge : styles.sidebarAvatar]}
>
<Avatar
style={[this.props.size === 'large' ? styles.avatarLarge : null]}
source={this.props.source}
/>
<Animated.View style={StyleSheet.flatten(indicatorStyles)}>
{this.props.isSyncing && (
<Icon
src={Sync}
fill={themeColors.textReversed}
width={6}
height={6}
/>
)}
</Animated.View>
</View>
);
}
}

AvatarWithIndicator.defaultProps = defaultProps;
AvatarWithIndicator.propTypes = propTypes;
AvatarWithIndicator.displayName = 'AvatarWithIndicator';
export default memo(AvatarWithIndicator);
export default AvatarWithIndicator;
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Profile from '../../../assets/images/profile.svg';
import Receipt from '../../../assets/images/receipt.svg';
import Send from '../../../assets/images/send.svg';
import SignOut from '../../../assets/images/sign-out.svg';
import Sync from '../../../assets/images/sync.svg';
import Trashcan from '../../../assets/images/trashcan.svg';
import Users from '../../../assets/images/users.svg';
import Upload from '../../../assets/images/upload.svg';
Expand Down Expand Up @@ -80,6 +81,7 @@ export {
Receipt,
Send,
SignOut,
Sync,
Trashcan,
Upload,
Users,
Expand Down
3 changes: 3 additions & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,7 @@ export default {
noPhoneNumber: 'Please enter a phone number including the country code e.g +447814266907',
maxParticipantsReached: 'You\'ve reached the maximum number of participants for a group chat.',
},
session: {
offlineMessage: 'Looks like you\'re not connected to internet. Can you check your connection and try again?',
},
};
4 changes: 4 additions & 0 deletions src/libs/actions/Session.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import CONFIG from '../../CONFIG';
import PushNotification from '../Notification/PushNotification';
import Timing from './Timing';
import CONST from '../../CONST';
import {translate} from '../translate';

let credentials = {};
Onyx.connect({
Expand Down Expand Up @@ -132,6 +133,9 @@ function fetchAccountDetails(login) {
}
Onyx.merge(ONYXKEYS.ACCOUNT, {error: response.message});
})
.catch(() => {
Onyx.merge(ONYXKEYS.ACCOUNT, {error: translate('', 'session.offlineMessage')});
})
.finally(() => {
Onyx.merge(ONYXKEYS.ACCOUNT, {loading: false});
});
Expand Down
8 changes: 4 additions & 4 deletions src/libs/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import translations from '../languages/translations';
/**
* Return translated string for given locale and phrase
*
* @param {String} locale eg 'en', 'es-ES'
* @param {String} [locale] eg 'en', 'es-ES'
* @param {String|Array} phrase
* @param {Object} variables
* @returns {string}
* @param {Object} [variables]
* @returns {String}
*/
function translate(locale, phrase, variables = {}) {
function translate(locale = 'en', phrase, variables = {}) {
const localeLanguage = locale.substring(0, 2);
const fullLocale = lodashGet(translations, locale, {});
const language = lodashGet(translations, localeLanguage, {});
Expand Down
8 changes: 8 additions & 0 deletions src/pages/home/sidebar/SidebarLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ const propTypes = {

/** Whether we have the necessary report data to load the sidebar */
initialReportDataLoaded: PropTypes.bool,

// Whether we are syncing app data
isSyncingData: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -84,6 +87,7 @@ const defaultProps = {
currentlyViewedReportID: '',
priorityMode: CONST.PRIORITY_MODE.DEFAULT,
initialReportDataLoaded: false,
isSyncingData: false,
};

class SidebarLinks extends React.Component {
Expand Down Expand Up @@ -143,6 +147,7 @@ class SidebarLinks extends React.Component {
<AvatarWithIndicator
source={this.props.myPersonalDetails.avatar}
isActive={this.props.network && !this.props.network.isOffline}
isSyncing={this.props.network && !this.props.network.isOffline && this.props.isSyncingData}
/>
</TouchableOpacity>
</View>
Expand Down Expand Up @@ -200,5 +205,8 @@ export default compose(
initialReportDataLoaded: {
key: ONYXKEYS.INITIAL_REPORT_DATA_LOADED,
},
isSyncingData: {
key: ONYXKEYS.IS_LOADING_AFTER_RECONNECT,
},
}),
)(SidebarLinks);
23 changes: 23 additions & 0 deletions src/styles/getAvatarWithIndicatorStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Get Indicator Styles while animating
*
* @param {Object} rotate
* @param {Object} scale
* @returns {Object}
*/
function getSyncingStyles(rotate, scale) {
return {
transform: [{
rotate: rotate.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '-360deg'],
}),
},
{
scale,
}],
};
}

// eslint-disable-next-line import/prefer-default-export
export {getSyncingStyles};
25 changes: 13 additions & 12 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,19 @@ const styles = {
width: 12,
zIndex: 10,
},

statusIndicatorLarge: {
borderColor: themeColors.componentBG,
borderRadius: 8,
borderWidth: 2,
position: 'absolute',
right: 4,
bottom: 4,
height: 16,
width: 16,
zIndex: 10,
},

statusIndicatorOnline: {
backgroundColor: themeColors.online,
},
Expand Down Expand Up @@ -1183,18 +1196,6 @@ const styles = {
height: 80,
},

statusIndicatorLarge: {
borderColor: themeColors.componentBG,
borderRadius: 8,
borderWidth: 2,
position: 'absolute',
right: 4,
bottom: 4,
height: 16,
width: 16,
zIndex: 10,
},

displayName: {
fontSize: variables.fontSizeLarge,
fontFamily: fontFamily.GTA_BOLD,
Expand Down