Skip to content

Commit

Permalink
Merge branch 'Expensify:main' into openOldDotLinks
Browse files Browse the repository at this point in the history
  • Loading branch information
mateusbra authored Apr 27, 2022
2 parents 7465c12 + 7632516 commit 56a72e3
Show file tree
Hide file tree
Showing 33 changed files with 308 additions and 158 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ This is a persistent storage solution wrapped in a Pub/Sub library. In general t
- Collections of data are usually not stored as a single key (eg. an array with multiple objects), but as individual keys+ID (eg. `report_1234`, `report_4567`, etc.). Store collections as individual keys when a component will bind directly to one of those keys. For example: reports are stored as individual keys because `OptionRow.js` binds to the individual report keys for each link. However, report actions are stored as an array of objects because nothing binds directly to a single report action.
- Onyx allows other code to subscribe to changes in data, and then publishes change events whenever data is changed
- Anything needing to read Onyx data needs to:
1. Know what key the data is stored in (for web, you can find this by looking in the JS console > Application > local storage)
1. Know what key the data is stored in (for web, you can find this by looking in the JS console > Application > IndexedDB > OnyxDB > keyvaluepairs)
2. Subscribe to changes of the data for a particular key or set of keys. React components use `withOnyx()` and non-React libs use `Onyx.connect()`.
3. Get initialized with the current value of that key from persistent storage (Onyx does this by calling `setState()` or triggering the `callback` with the values currently on disk as part of the connection process)
- Subscribing to Onyx keys is done using a constant defined in `ONYXKEYS`. Each Onyx key represents either a collection of items or a specific entry in storage. For example, since all reports are stored as individual keys like `report_1234`, if code needs to know about all the reports (eg. display a list of them in the nav menu), then it would subscribe to the key `ONYXKEYS.COLLECTION.REPORT`.
Expand Down
9 changes: 3 additions & 6 deletions __mocks__/@react-native-community/netinfo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
export default {
configure: () => {},
fetch: () => {},
addEventListener: () => {},
useNetInfo: () => {},
};
import NetInfoMock from '@react-native-community/netinfo/jest/netinfo-mock';

export default NetInfoMock;
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001015600
versionName "1.1.56-0"
versionCode 1001015703
versionName "1.1.57-3"
}
splits {
abi {
Expand Down
12 changes: 12 additions & 0 deletions assets/images/connect.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.56</string>
<string>1.1.57</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -30,7 +30,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.1.56.0</string>
<string>1.1.57.3</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.1.56</string>
<string>1.1.57</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.56.0</string>
<string>1.1.57.3</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.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.1.56-0",
"version": "1.1.57-3",
"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 Expand Up @@ -42,7 +42,7 @@
"@react-native-community/cli": "6.2.0",
"@react-native-community/clipboard": "^1.5.1",
"@react-native-community/datetimepicker": "^3.5.2",
"@react-native-community/netinfo": "^8.0.0",
"@react-native-community/netinfo": "^8.3.0",
"@react-native-community/progress-bar-android": "^1.0.4",
"@react-native-community/progress-view": "^1.2.3",
"@react-native-firebase/analytics": "^12.3.0",
Expand Down
2 changes: 1 addition & 1 deletion src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ const CONST = {
},

// There's a limit of 60k characters in Auth - https://github.com/Expensify/Auth/blob/198d59547f71fdee8121325e8bc9241fc9c3236a/auth/lib/Request.h#L28
MAX_COMMENT_LENGTH: 60_000,
MAX_COMMENT_LENGTH: 60000,
};

export default CONST;
54 changes: 46 additions & 8 deletions src/components/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,28 @@ import Icon from './Icon';
import CONST from '../CONST';
import * as StyleUtils from '../styles/StyleUtils';
import HapticFeedback from '../libs/HapticFeedback';
import * as Expensicons from './Icon/Expensicons';
import colors from '../styles/colors';

const propTypes = {
/** The text for the button label */
text: PropTypes.string,

/** Boolean whether to display the right icon */
shouldShowRightIcon: PropTypes.bool,

/** The icon asset to display to the left of the text */
icon: PropTypes.func,

/** The icon asset to display to the right of the text */
iconRight: PropTypes.func,

/** The fill color to pass into the icon. */
iconFill: PropTypes.string,

/** Any additional styles to pass to the icon container. */
iconStyles: PropTypes.arrayOf(PropTypes.object),

/** Small sized button */
small: PropTypes.bool,

Expand All @@ -27,6 +41,9 @@ const propTypes = {
/** medium sized button */
medium: PropTypes.bool,

/** Extra large sized button */
extraLarge: PropTypes.bool,

/** Indicates whether the button should be disabled and in the loading state */
isLoading: PropTypes.bool,

Expand Down Expand Up @@ -84,12 +101,17 @@ const propTypes = {

const defaultProps = {
text: '',
shouldShowRightIcon: false,
icon: null,
iconRight: Expensicons.ArrowRight,
iconFill: colors.white,
iconStyles: [],
isLoading: false,
isDisabled: false,
small: false,
large: false,
medium: false,
extraLarge: false,
onPress: () => {},
onLongPress: () => {},
onPressIn: () => {},
Expand Down Expand Up @@ -158,6 +180,7 @@ class Button extends Component {
this.props.small && styles.buttonSmallText,
this.props.medium && styles.buttonMediumText,
this.props.large && styles.buttonLargeText,
this.props.extraLarge && styles.buttonExtraLargeText,
this.props.success && styles.buttonSuccessText,
this.props.danger && styles.buttonDangerText,
...this.props.textStyles,
Expand All @@ -169,15 +192,29 @@ class Button extends Component {

if (this.props.icon) {
return (
<View style={[styles.flexRow, styles.alignItemsCenter]}>
<View style={styles.mr1}>
<Icon
src={this.props.icon}
fill={themeColors.heading}
small={this.props.small}
/>
<View style={[styles.justifyContentBetween, styles.flexRow]}>
<View style={[styles.alignItemsCenter, styles.flexRow]}>
<View style={[
styles.mr1,
...this.props.iconStyles,
]}
>
<Icon
src={this.props.icon}
fill={this.props.iconFill}
small={this.props.small}
/>
</View>
{textComponent}
</View>
{textComponent}
{this.props.shouldShowRightIcon && (
<View>
<Icon
src={this.props.iconRight}
fill={this.props.iconFill}
/>
</View>
)}
</View>
);
}
Expand Down Expand Up @@ -216,6 +253,7 @@ class Button extends Component {
this.props.small ? styles.buttonSmall : undefined,
this.props.medium ? styles.buttonMedium : undefined,
this.props.large ? styles.buttonLarge : undefined,
this.props.extraLarge ? styles.buttonExtraLarge : undefined,
this.props.success ? styles.buttonSuccess : undefined,
this.props.danger ? styles.buttonDanger : undefined,
(this.props.isDisabled && this.props.success) ? styles.buttonSuccessDisabled : undefined,
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import ActiveRoomAvatar from '../../../assets/images/avatars/room.svg';
import DeletedRoomAvatar from '../../../assets/images/avatars/deleted-room.svg';
import AdminRoomAvatar from '../../../assets/images/avatars/admin-room.svg';
import AnnounceRoomAvatar from '../../../assets/images/avatars/announce-room.svg';
import Connect from '../../../assets/images/connect.svg';

export {
ActiveRoomAvatar,
Expand All @@ -98,6 +99,7 @@ export {
Close,
ClosedSign,
Concierge,
Connect,
CreditCard,
DeletedRoomAvatar,
DownArrow,
Expand Down
10 changes: 7 additions & 3 deletions src/libs/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,17 @@ NetworkEvents.registerLogHandler(() => Log);
// Handle response event sent by the Network
NetworkEvents.onResponse((queuedRequest, response) => {
if (queuedRequest.command !== 'Log') {
Log.info('Finished API request', false, {
const logParams = {
command: queuedRequest.command,
type: queuedRequest.type,
shouldUseSecure: queuedRequest.shouldUseSecure,
jsonCode: response.jsonCode,
requestID: response.requestID,
});
};
if (queuedRequest.command === 'Get') {
logParams.returnValueList = lodashGet(queuedRequest, 'data.returnValueList', '');
logParams.nvpNames = lodashGet(queuedRequest, 'data.nvpNames', '');
}
Log.info('Finished API request', false, logParams);
}

if (response.jsonCode === CONST.JSON_CODE.NOT_AUTHENTICATED) {
Expand Down
5 changes: 5 additions & 0 deletions src/libs/Network/enhanceParameters.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import lodashGet from 'lodash/get';
import _ from 'underscore';
import CONFIG from '../../CONFIG';
import getPlatform from '../getPlatform';
import * as NetworkStore from './NetworkStore';

/**
Expand Down Expand Up @@ -40,6 +41,10 @@ export default function enhanceParameters(command, parameters) {

finalParameters.referer = CONFIG.EXPENSIFY.EXPENSIFY_CASH_REFERER;

// In addition to the referer (ecash), we pass the platform to help differentiate what device type
// is sending the request.
finalParameters.platform = getPlatform();

// This application does not save its authToken in cookies like the classic Expensify app.
// Setting api_setCookie to false will ensure that the Expensify API doesn't set any cookies
// and prevents interfering with the cookie authToken that Expensify classic uses.
Expand Down
11 changes: 7 additions & 4 deletions src/libs/Network/processRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ function logRequestDetails(request, parameters) {
return;
}

NetworkEvents.getLogger().info('Making API request', false, {
const logParams = {
command: request.command,
type: request.type,
shouldUseSecure: request.shouldUseSecure,
rvl: parameters.returnValueList,
});
};
if (request.command === 'Get') {
logParams.returnValueList = parameters.returnValueList;
logParams.nvpNames = parameters.nvpNames;
}
NetworkEvents.getLogger().info('Making API request', false, logParams);
}

/**
Expand Down
15 changes: 6 additions & 9 deletions src/libs/NetworkConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import CONST from '../CONST';
let unsubscribeFromNetInfo;
let unsubscribeFromAppState;
let isOffline = false;
let hasPendingNetworkCheck = true;
let hasPendingNetworkCheck = false;

// Holds all of the callbacks that need to be triggered when the network reconnects
const reconnectionCallbacks = [];
Expand Down Expand Up @@ -73,9 +73,6 @@ function subscribeToNetInfo() {
unsubscribeFromNetInfo = NetInfo.addEventListener((state) => {
Log.info('[NetworkConnection] NetInfo state change', false, state);
setOfflineStatus(state.isInternetReachable === false);

// When internet state is indeterminate a check is already running. Set the flag to prevent duplicate checks
hasPendingNetworkCheck = state.isInternetReachable === null;
});
}

Expand Down Expand Up @@ -113,18 +110,18 @@ function onReconnect(callback) {
reconnectionCallbacks.push(callback);
}

/**
* Refresh NetInfo state.
*/
function recheckNetworkConnection() {
if (hasPendingNetworkCheck) {
return;
}

Log.info('[NetworkConnection] recheck NetInfo');
hasPendingNetworkCheck = true;

if (unsubscribeFromNetInfo) {
unsubscribeFromNetInfo();
}
subscribeToNetInfo();
NetInfo.refresh()
.finally(() => hasPendingNetworkCheck = false);
}

NetworkEvents.onRecheckNeeded(recheckNetworkConnection);
Expand Down
Loading

0 comments on commit 56a72e3

Please sign in to comment.