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.58-1 on staging #3255

Merged
merged 19 commits into from
Jun 1, 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 1001005800
versionName "1.0.58-0"
versionCode 1001005801
versionName "1.0.58-1"
}
splits {
abi {
Expand Down
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.58.0</string>
<string>1.0.58.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.58.0</string>
<string>1.0.58.1</string>
</dict>
</plist>
8 changes: 4 additions & 4 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": "expensify.cash",
"version": "1.0.58-0",
"version": "1.0.58-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
7 changes: 7 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ const CONST = {
PHONE_E164_PLUS: /^\+?[1-9]\d{1,14}$/,
NON_ALPHA_NUMERIC: /[^A-Za-z0-9+]/g,
},

GROWL: {
SUCCESS: 'success',
ERROR: 'error',
WARNING: 'warning',
DURATION: 2000,
},
};

export default CONST;
3 changes: 3 additions & 0 deletions src/Expensify.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import styles from './styles/styles';
import PushNotification from './libs/Notification/PushNotification';
import UpdateAppModal from './components/UpdateAppModal';
import Visibility from './libs/Visibility';
import GrowlNotification from './components/GrowlNotification';
import {growlRef} from './libs/Growl';

// Initialize the store when the app loads for the first time
Onyx.init({
Expand Down Expand Up @@ -156,6 +158,7 @@ class Expensify extends PureComponent {
}
return (
<>
<GrowlNotification ref={growlRef} />
{/* We include the modal for showing a new update at the top level so the option is always present. */}
{this.props.updateAvailable ? <UpdateAppModal /> : null}
<NavigationRoot authenticated={Boolean(this.getAuthToken())} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Animated} from 'react-native';
import PropTypes from 'prop-types';
import {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
import {windowDimensionsPropTypes} from '../../withWindowDimensions';

const propTypes = {
/** GrowlNotification content */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import {Animated} from 'react-native';
import styles from '../../../styles/styles';
import withWindowDimensions from '../../../components/withWindowDimensions';
import withWindowDimensions from '../../withWindowDimensions';
import propTypes from './GrowlNotificationContainerPropTypes';

const GrowlNotificationContainer = ({children, translateY, isSmallScreenWidth}) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import {Animated} from 'react-native';
import {SafeAreaInsetsContext} from 'react-native-safe-area-context';
import styles, {getSafeAreaPadding} from '../../../styles/styles';
import propTypes from './GrowlNotificationContainerPropTypes';

const GrowlNotificationContainer = ({children, translateY}) => (
<SafeAreaInsetsContext.Consumer>
{insets => (
<Animated.View
style={[
styles.growlNotificationContainer,
getSafeAreaPadding(insets),
styles.growlNotificationTranslateY(translateY),
]}
>
{children}
</Animated.View>
)}
</SafeAreaInsetsContext.Consumer>
);

GrowlNotificationContainer.propTypes = propTypes;

export default GrowlNotificationContainer;
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ import {
Directions, FlingGestureHandler, State, TouchableWithoutFeedback,
} from 'react-native-gesture-handler';
import colors from '../../styles/colors';
import Icon from '../../components/Icon';
import {Checkmark, Exclamation} from '../../components/Icon/Expensicons';
import Icon from '../Icon';
import {Checkmark, Exclamation} from '../Icon/Expensicons';
import styles from '../../styles/styles';
import GrowlNotificationContainer from './GrowlNotificationContainer';
import CONST from '../../CONST';

const types = {
success: {
[CONST.GROWL.SUCCESS]: {
icon: Checkmark,
iconColor: colors.green,
},
error: {
[CONST.GROWL.ERROR]: {
icon: Exclamation,
iconColor: colors.red,
},
warning: {
[CONST.GROWL.WARNING]: {
icon: Exclamation,
iconColor: colors.yellow,
},
Expand All @@ -47,9 +48,9 @@ class GrowlNotification extends Component {
*
* @param {String} bodyText
* @param {String} type
* @param {Number} duration - 2000
* @param {Number} duration
*/
show(bodyText, type, duration = 2000) {
show(bodyText, type, duration) {
this.setState({
bodyText,
type,
Expand Down
40 changes: 37 additions & 3 deletions src/components/TextInputFocusable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import {TextInput, StyleSheet} from 'react-native';
import PropTypes from 'prop-types';
import _ from 'underscore';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import Growl from '../../libs/Growl';
import themeColors from '../../styles/themes/default';
import CONST from '../../CONST';

const propTypes = {
/** Maximum number of lines in the text input */
Expand Down Expand Up @@ -108,6 +110,11 @@ class TextInputFocusable extends React.Component {
end: initialValue.length,
},
};
this.selection = {
start: initialValue.length,
end: initialValue.length,
};
this.saveSelection = this.saveSelection.bind(this);
}

componentDidMount() {
Expand Down Expand Up @@ -176,6 +183,17 @@ class TextInputFocusable extends React.Component {
return newNumberOfLines;
}

/**
* Keeps track of user cursor position on the Composer
*
* @param {{nativeEvent: {selection: any}}} event
* @memberof TextInputFocusable
*/
saveSelection(event) {
this.selection = event.nativeEvent.selection;
this.props.onSelectionChange(event);
}

/**
* Check the paste event for an attachment, parse the data and
* call onPasteFile from props with the selected file
Expand All @@ -185,13 +203,15 @@ class TextInputFocusable extends React.Component {
checkForAttachment(event) {
const {files, types} = event.clipboardData;
const TEXT_HTML = 'text/html';
const TEXT_PLAIN = 'text/plain';
if (files.length > 0) {
// Prevent the default so we do not post the file name into the text box
event.preventDefault();
this.props.onPasteFile(event.clipboardData.files[0]);
} else if (types.includes(TEXT_HTML)) {
const domparser = new DOMParser();
const embededImages = domparser.parseFromString(event.clipboardData.getData(TEXT_HTML), TEXT_HTML).images;
const pastedText = event.clipboardData.getData(TEXT_PLAIN);
if (embededImages.length > 0) {
event.preventDefault();
fetch(embededImages[0].src)
Expand All @@ -208,9 +228,23 @@ class TextInputFocusable extends React.Component {
return new File([x], `pasted_image.${extension}`, {});
})
.then(this.props.onPasteFile)
.catch((error) => {
.catch(() => {
const errorDesc = this.props.translate('textInputFocusable.problemGettingImageYouPasted');
alert(`${errorDesc}. \n${error.message}`);
Growl.show(errorDesc, CONST.GROWL.ERROR);

/*
* Since we intercepted the user-triggered paste event to check for attachments,
* we need to manually set the value and call the `onChangeText` handler.
* Synthetically-triggered paste events do not affect the document's contents.
* See https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event for more details.
*/
const beforeCursorText = this.textInput.value.substring(0, this.selection.start);
const afterCursorText = this.textInput.value.substring(this.selection.end);
this.textInput.value = beforeCursorText + pastedText + afterCursorText;
this.updateNumberOfLines();
this.props.onChangeText(this.textInput.value);
const newCursorPosition = beforeCursorText.length + pastedText.length;
this.setState({selection: {start: newCursorPosition, end: newCursorPosition}});
});
}
}
Expand Down Expand Up @@ -247,12 +281,12 @@ class TextInputFocusable extends React.Component {
onChange={() => {
this.updateNumberOfLines();
}}
onSelectionChange={this.saveSelection}
numberOfLines={this.state.numberOfLines}
style={propStyles}
/* eslint-disable-next-line react/jsx-props-no-spreading */
{...propsWithoutStyles}
disabled={this.props.isDisabled}
onSelectionChange={this.props.onSelectionChange}
/>
);
}
Expand Down
18 changes: 18 additions & 0 deletions src/libs/Growl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import CONST from '../CONST';

export const growlRef = React.createRef();

/**
* Show the growl notification
*
* @param {String} bodyText
* @param {String} type
* @param {Number} [duration]
*/
function show(bodyText, type, duration = CONST.GROWL.DURATION) {
growlRef.current.show(bodyText, type, duration);
}


export default {show};

This file was deleted.

6 changes: 2 additions & 4 deletions src/pages/settings/Profile/ProfilePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import CreateMenu from '../../../components/CreateMenu';
import Picker from '../../../components/Picker';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import compose from '../../../libs/compose';
import GrowlNotification from '../../../libs/GrowlNotification';
import Button from '../../../components/Button';
import Growl from '../../../libs/Growl';

const propTypes = {
/* Onyx Props */
Expand Down Expand Up @@ -131,7 +131,6 @@ class ProfilePage extends Component {
this.setAutomaticTimezone = this.setAutomaticTimezone.bind(this);
this.getLogins = this.getLogins.bind(this);
this.createMenuItems = this.createMenuItems.bind(this);
this.growlNotification = undefined;
}

componentDidUpdate(prevProps) {
Expand Down Expand Up @@ -211,7 +210,7 @@ class ProfilePage extends Component {
},
});

this.growlNotification.show(this.props.translate('profilePage.growlMessageOnSave'), 'success', 3000);
Growl.show(this.props.translate('profilePage.growlMessageOnSave'), CONST.GROWL.SUCCESS, 3000);
}

/**
Expand Down Expand Up @@ -261,7 +260,6 @@ class ProfilePage extends Component {

return (
<ScreenWrapper>
<GrowlNotification ref={el => this.growlNotification = el} />
<HeaderWithCloseButton
title={this.props.translate('common.profile')}
shouldShowBackButton
Expand Down
4 changes: 2 additions & 2 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -1466,12 +1466,12 @@ const styles = {
justifyContent: 'flex-start',
position: 'absolute',
width: '100%',
top: 20,
...spacing.ph5,
},

growlNotificationDesktopContainer: {
maxWidth: '380px',
top: '20px',
maxWidth: 380,
right: 0,
position: 'fixed',
},
Expand Down